From 8e94efe4ba7841ca83f85bc363488805e9eb2ec4 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sat, 13 Feb 2021 00:25:53 +0100 Subject: [PATCH] Move asn1_skip_integer to the asn1_helpers module Signed-off-by: Gilles Peskine --- tests/include/test/asn1_helpers.h | 24 +++++++ tests/src/asn1_helpers.c | 49 +++++++++++++++ tests/suites/test_suite_psa_crypto.function | 69 ++++----------------- 3 files changed, 86 insertions(+), 56 deletions(-) diff --git a/tests/include/test/asn1_helpers.h b/tests/include/test/asn1_helpers.h index ddcc0c9a6..91ae26026 100644 --- a/tests/include/test/asn1_helpers.h +++ b/tests/include/test/asn1_helpers.h @@ -22,5 +22,29 @@ #include "test/helpers.h" +/** Skip past an INTEGER in an ASN.1 buffer. + * + * Mark the current test case as failed in any of the following conditions: + * - The buffer does not start with an ASN.1 INTEGER. + * - The integer's size or parity does not match the constraints expressed + * through \p min_bits, \p max_bits and \p must_be_odd. + * + * \param p Upon entry, `*p` points to the first byte of the + * buffer to parse. + * On successful return, `*p` points to the first byte + * after the parsed INTEGER. + * On failure, `*p` is unspecified. + * \param end The end of the ASN.1 buffer. + * \param min_bits Fail the test case if the integer does not have at + * least this many significant bits. + * \param max_bits Fail the test case if the integer has more than + * this many significant bits. + * \param must_be_odd Fail the test case if the integer is even. + * + * \return \c 0 if the test failed, otherwise 1. + */ +int mbedtls_test_asn1_skip_integer( unsigned char **p, const unsigned char *end, + size_t min_bits, size_t max_bits, + int must_be_odd ); #endif /* ASN1_HELPERS_H */ diff --git a/tests/src/asn1_helpers.c b/tests/src/asn1_helpers.c index 6ffdca90a..79aa166ce 100644 --- a/tests/src/asn1_helpers.c +++ b/tests/src/asn1_helpers.c @@ -23,3 +23,52 @@ #include #include +#if defined(MBEDTLS_ASN1_PARSE_C) + +#include + +int mbedtls_test_asn1_skip_integer( unsigned char **p, const unsigned char *end, + size_t min_bits, size_t max_bits, + int must_be_odd ) +{ + size_t len; + size_t actual_bits; + unsigned char msb; + TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_INTEGER ), + 0 ); + + /* Check if the retrieved length doesn't extend the actual buffer's size. + * It is assumed here, that end >= p, which validates casting to size_t. */ + TEST_ASSERT( len <= (size_t)( end - *p) ); + + /* Tolerate a slight departure from DER encoding: + * - 0 may be represented by an empty string or a 1-byte string. + * - The sign bit may be used as a value bit. */ + if( ( len == 1 && ( *p )[0] == 0 ) || + ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) ) + { + ++( *p ); + --len; + } + if( min_bits == 0 && len == 0 ) + return( 1 ); + msb = ( *p )[0]; + TEST_ASSERT( msb != 0 ); + actual_bits = 8 * ( len - 1 ); + while( msb != 0 ) + { + msb >>= 1; + ++actual_bits; + } + TEST_ASSERT( actual_bits >= min_bits ); + TEST_ASSERT( actual_bits <= max_bits ); + if( must_be_odd ) + TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 ); + *p += len; + return( 1 ); +exit: + return( 0 ); +} + +#endif /* MBEDTLS_ASN1_PARSE_C */ diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 37cc5514a..f0b86476f 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -12,6 +12,7 @@ #include "psa/crypto.h" #include "psa_crypto_slot_management.h" +#include "test/asn1_helpers.h" #include "test/psa_crypto_helpers.h" /** An invalid export length that will never be set by psa_export_key(). */ @@ -818,50 +819,6 @@ exit: return( ok ); } -int asn1_skip_integer( unsigned char **p, const unsigned char *end, - size_t min_bits, size_t max_bits, - int must_be_odd ) -{ - size_t len; - size_t actual_bits; - unsigned char msb; - TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_INTEGER ), - 0 ); - - /* Check if the retrieved length doesn't extend the actual buffer's size. - * It is assumed here, that end >= p, which validates casting to size_t. */ - TEST_ASSERT( len <= (size_t)( end - *p) ); - - /* Tolerate a slight departure from DER encoding: - * - 0 may be represented by an empty string or a 1-byte string. - * - The sign bit may be used as a value bit. */ - if( ( len == 1 && ( *p )[0] == 0 ) || - ( len > 1 && ( *p )[0] == 0 && ( ( *p )[1] & 0x80 ) != 0 ) ) - { - ++( *p ); - --len; - } - if( min_bits == 0 && len == 0 ) - return( 1 ); - msb = ( *p )[0]; - TEST_ASSERT( msb != 0 ); - actual_bits = 8 * ( len - 1 ); - while( msb != 0 ) - { - msb >>= 1; - ++actual_bits; - } - TEST_ASSERT( actual_bits >= min_bits ); - TEST_ASSERT( actual_bits <= max_bits ); - if( must_be_odd ) - TEST_ASSERT( ( ( *p )[len-1] & 1 ) != 0 ); - *p += len; - return( 1 ); -exit: - return( 0 ); -} - int mbedtls_test_psa_exported_key_sanity_check( psa_key_type_t type, size_t bits, uint8_t *exported, size_t exported_length ) @@ -913,25 +870,25 @@ int mbedtls_test_psa_exported_key_sanity_check( MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ), 0 ); TEST_EQUAL( p + len, end ); - if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, 0, 0, 0 ) ) goto exit; - if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, bits, bits, 1 ) ) goto exit; - if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, 2, bits, 1 ) ) goto exit; /* Require d to be at least half the size of n. */ - if( ! asn1_skip_integer( &p, end, bits / 2, bits, 1 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, bits / 2, bits, 1 ) ) goto exit; /* Require p and q to be at most half the size of n, rounded up. */ - if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) ) goto exit; - if( ! asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) ) goto exit; - if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) ) goto exit; - if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) ) goto exit; - if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) ) goto exit; TEST_EQUAL( p, end ); } @@ -964,9 +921,9 @@ int mbedtls_test_psa_exported_key_sanity_check( MBEDTLS_ASN1_CONSTRUCTED ), 0 ); TEST_EQUAL( p + len, end ); - if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, bits, bits, 1 ) ) goto exit; - if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) ) + if( ! mbedtls_test_asn1_skip_integer( &p, end, 2, bits, 1 ) ) goto exit; TEST_EQUAL( p, end ); } @@ -5632,7 +5589,7 @@ void generate_key_rsa( int bits_arg, TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ); - TEST_ASSERT( asn1_skip_integer( &p, end, bits, bits, 1 ) ); + TEST_ASSERT( mbedtls_test_asn1_skip_integer( &p, end, bits, bits, 1 ) ); TEST_EQUAL( 0, mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_INTEGER ) ); if( len >= 1 && p[0] == 0 )