mirror of
				https://github.com/yuzu-emu/mbedtls.git
				synced 2025-10-22 08:27:09 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			414 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			414 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| #line 2 "suites/target_test.function"
 | |
| 
 | |
| #include "greentea-client/test_env.h"
 | |
| 
 | |
| /**
 | |
|  * \brief       Increments pointer and asserts that it does not overflow.
 | |
|  *
 | |
|  * \param p     Pointer to byte array
 | |
|  * \param start Pointer to start of byte array
 | |
|  * \param len   Length of byte array
 | |
|  * \param step  Increment size
 | |
|  *
 | |
|  */
 | |
| #define INCR_ASSERT(p, start, len, step) do                     \
 | |
| {                                                               \
 | |
|     assert( ( p ) >= ( start ) );                               \
 | |
|     assert( sizeof( *( p ) ) == sizeof( *( start ) ) );         \
 | |
|     /* <= is checked to support use inside a loop where         \
 | |
|        pointer is incremented after reading data.       */      \
 | |
|     assert( (uint32_t)( ( ( p ) - ( start ) ) + ( step ) ) <= ( len ) );\
 | |
|     ( p ) += ( step );                                          \
 | |
| }                                                               \
 | |
| while( 0 )
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * \brief       4 byte align unsigned char pointer
 | |
|  *
 | |
|  * \param p     Pointer to byte array
 | |
|  * \param start Pointer to start of byte array
 | |
|  * \param len   Length of byte array
 | |
|  *
 | |
|  */
 | |
| #define ALIGN_32BIT(p, start, len) do               \
 | |
| {                                                   \
 | |
|     uint32_t align = ( - (uintptr_t)( p ) ) % 4;    \
 | |
|     INCR_ASSERT( ( p ), ( start ), ( len ), align );\
 | |
| }                                                   \
 | |
| while( 0 )
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * \brief       Verify dependencies. Dependency identifiers are
 | |
|  *              encoded in the buffer as 8 bit unsigned integers.
 | |
|  *
 | |
|  * \param count     Number of dependencies.
 | |
|  * \param dep_p     Pointer to buffer.
 | |
|  *
 | |
|  * \return          DEPENDENCY_SUPPORTED if success else DEPENDENCY_NOT_SUPPORTED.
 | |
|  */
 | |
| int verify_dependencies( uint8_t count, uint8_t * dep_p )
 | |
| {
 | |
|     uint8_t i;
 | |
|     for ( i = 0; i < count; i++ )
 | |
|     {
 | |
|         if ( dep_check( (int)(dep_p[i]) ) != DEPENDENCY_SUPPORTED )
 | |
|             return( DEPENDENCY_NOT_SUPPORTED );
 | |
|     }
 | |
|     return( DEPENDENCY_SUPPORTED );
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * \brief       Receives unsigned integer on serial interface.
 | |
|  *              Integers are encoded in network order.
 | |
|  *
 | |
|  * \param none
 | |
|  *
 | |
|  * \return      unsigned int
 | |
|  */
 | |
| uint32_t receive_uint32()
 | |
| {
 | |
|     uint32_t value;
 | |
|     value =  (uint8_t)greentea_getc() << 24;
 | |
|     value |= (uint8_t)greentea_getc() << 16;
 | |
|     value |= (uint8_t)greentea_getc() << 8;
 | |
|     value |= (uint8_t)greentea_getc();
 | |
|     return( (uint32_t)value );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief       Parses out an unsigned 32 int value from the byte array.
 | |
|  *              Integers are encoded in network order.
 | |
|  *
 | |
|  * \param p     Pointer to byte array
 | |
|  *
 | |
|  * \return      unsigned int
 | |
|  */
 | |
| uint32_t parse_uint32( uint8_t * p )
 | |
| {
 | |
|     uint32_t value;
 | |
|     value =  *p++ << 24;
 | |
|     value |= *p++ << 16;
 | |
|     value |= *p++ << 8;
 | |
|     value |= *p;
 | |
|     return( value );
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * \brief       Receives test data on serial as greentea key,value pair:
 | |
|  *              {{<length>;<byte array>}}
 | |
|  *
 | |
|  * \param data_len  Out pointer to hold received data length.
 | |
|  *
 | |
|  * \return      Byte array.
 | |
|  */
 | |
| uint8_t * receive_data( uint32_t * data_len )
 | |
| {
 | |
|     uint32_t i = 0, errors = 0;
 | |
|     char c;
 | |
|     uint8_t * data = NULL;
 | |
| 
 | |
|     /* Read opening braces */
 | |
|     i = 0;
 | |
|     while ( i < 2 )
 | |
|     {
 | |
|         c = greentea_getc();
 | |
|         /* Ignore any prevous CR LF characters */
 | |
|         if ( c == '\n' || c == '\r' )
 | |
|             continue;
 | |
|         i++;
 | |
|         if ( c != '{' )
 | |
|             return( NULL );
 | |
|     }
 | |
| 
 | |
|     /* Read data length */
 | |
|     *data_len = receive_uint32();
 | |
|     data = (uint8_t *)malloc( *data_len );
 | |
|     assert( data != NULL );
 | |
| 
 | |
|     greentea_getc(); // read ';' received after key i.e. *data_len
 | |
| 
 | |
|     for( i = 0; i < *data_len; i++ )
 | |
|         data[i] = greentea_getc();
 | |
| 
 | |
|     /* Read closing braces */
 | |
|     for( i = 0; i < 2; i++ )
 | |
|     {
 | |
|         c = greentea_getc();
 | |
|         if ( c != '}' )
 | |
|         {
 | |
|             errors++;
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ( errors )
 | |
|     {
 | |
|         free( data );
 | |
|         data = NULL;
 | |
|         *data_len = 0;
 | |
|     }
 | |
| 
 | |
|     return( data );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief       Parse the received byte array and count the number of arguments
 | |
|  *              to the test function passed as type hex.
 | |
|  *
 | |
|  * \param count     Parameter count
 | |
|  * \param data      Received Byte array
 | |
|  * \param data_len  Byte array length
 | |
|  *
 | |
|  * \return      count of hex params
 | |
|  */
 | |
| uint32_t find_hex_count( uint8_t count, uint8_t * data, uint32_t data_len )
 | |
| {
 | |
|     uint32_t i = 0, sz = 0;
 | |
|     char c;
 | |
|     uint8_t * p = NULL;
 | |
|     uint32_t hex_count = 0;
 | |
| 
 | |
|     p = data;
 | |
| 
 | |
|     for( i = 0; i < count; i++ )
 | |
|     {
 | |
|         c = (char)*p;
 | |
|         INCR_ASSERT( p, data, data_len, 1 );
 | |
| 
 | |
|         /* Align p to 4 bytes for int, expression, string len or hex length */
 | |
|         ALIGN_32BIT( p, data, data_len );
 | |
| 
 | |
|         /* Network to host conversion */
 | |
|         sz = (int32_t)parse_uint32( p );
 | |
| 
 | |
|         INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
 | |
| 
 | |
|         if ( c == 'H' || c == 'S' )
 | |
|         {
 | |
|             INCR_ASSERT( p, data, data_len, sz );
 | |
|             hex_count += ( c == 'H' )?1:0;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return( hex_count );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief       Parses received byte array for test parameters.
 | |
|  *
 | |
|  * \param count     Parameter count
 | |
|  * \param data      Received Byte array
 | |
|  * \param data_len  Byte array length
 | |
|  * \param error     Parsing error out variable.
 | |
|  *
 | |
|  * \return      Array of parsed parameters allocated on heap.
 | |
|  *              Note: Caller has the responsibility to delete
 | |
|  *                    the memory after use.
 | |
|  */
 | |
| void ** parse_parameters( uint8_t count, uint8_t * data, uint32_t data_len,
 | |
|                           int * error )
 | |
| {
 | |
|     uint32_t i = 0, hex_count = 0;
 | |
|     char c;
 | |
|     void ** params = NULL;
 | |
|     void ** cur = NULL;
 | |
|     uint8_t * p = NULL;
 | |
| 
 | |
|     hex_count = find_hex_count(count, data, data_len);
 | |
| 
 | |
|     params = (void **)malloc( sizeof( void *) * ( count + hex_count ) );
 | |
|     assert( params != NULL );
 | |
|     cur = params;
 | |
| 
 | |
|     p = data;
 | |
| 
 | |
|     /* Parameters */
 | |
|     for( i = 0; i < count; i++ )
 | |
|     {
 | |
|         c = (char)*p;
 | |
|         INCR_ASSERT( p, data, data_len, 1 );
 | |
| 
 | |
|         /* Align p to 4 bytes for int, expression, string len or hex length */
 | |
|         ALIGN_32BIT( p, data, data_len );
 | |
| 
 | |
|         /* Network to host conversion */
 | |
|         *( (int32_t *)p ) = (int32_t)parse_uint32( p );
 | |
| 
 | |
|         switch( c )
 | |
|         {
 | |
|             case 'E':
 | |
|                 {
 | |
|                     if ( get_expression( *( (int32_t *)p ), (int32_t *)p ) )
 | |
|                     {
 | |
|                         *error = KEY_VALUE_MAPPING_NOT_FOUND;
 | |
|                         goto exit;
 | |
|                     }
 | |
|                 } /* Intentional fall through */
 | |
|             case 'I':
 | |
|                 {
 | |
|                     *cur++ = (void *)p;
 | |
|                     INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
 | |
|                 }
 | |
|                 break;
 | |
|             case 'H': /* Intentional fall through */
 | |
|             case 'S':
 | |
|                 {
 | |
|                     uint32_t * sz = (uint32_t *)p;
 | |
|                     INCR_ASSERT( p, data, data_len, sizeof( int32_t ) );
 | |
|                     *cur++ = (void *)p;
 | |
|                     if ( c == 'H' )
 | |
|                         *cur++ = (void *)sz;
 | |
|                     INCR_ASSERT( p, data, data_len, ( *sz ) );
 | |
|                 }
 | |
|                 break;
 | |
|             default:
 | |
|                     {
 | |
|                         *error = DISPATCH_INVALID_TEST_DATA;
 | |
|                         goto exit;
 | |
|                     }
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
| exit:
 | |
|     if ( *error )
 | |
|     {
 | |
|         free( params );
 | |
|         params = NULL;
 | |
|     }
 | |
| 
 | |
|     return( params );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief       Sends greentea key and int value pair to host.
 | |
|  *
 | |
|  * \param key   key string
 | |
|  * \param value integer value
 | |
|  *
 | |
|  * \return      void
 | |
|  */
 | |
| void send_key_integer( char * key, int value )
 | |
| {
 | |
|     char str[50];
 | |
|     snprintf( str, sizeof( str ), "%d", value );
 | |
|     greentea_send_kv( key, str );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief       Sends test setup failure to the host.
 | |
|  *
 | |
|  * \param failure   Test set failure
 | |
|  *
 | |
|  * \return      void
 | |
|  */
 | |
| void send_failure( int failure )
 | |
| {
 | |
|     send_key_integer( "F", failure );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief       Sends test status to the host.
 | |
|  *
 | |
|  * \param status    Test status (PASS=0/FAIL=!0)
 | |
|  *
 | |
|  * \return      void
 | |
|  */
 | |
| void send_status( int status )
 | |
| {
 | |
|     send_key_integer( "R", status );
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * \brief       Embedded implementation of execute_tests().
 | |
|  *              Ignores command line and received test data
 | |
|  *              on serial.
 | |
|  *
 | |
|  * \param argc  not used
 | |
|  * \param argv  not used
 | |
|  *
 | |
|  * \return      Program exit status.
 | |
|  */
 | |
| int execute_tests( int args, const char ** argv )
 | |
| {
 | |
|     int ret = 0;
 | |
|     uint32_t data_len = 0;
 | |
|     uint8_t count = 0, function_id;
 | |
|     void ** params = NULL;
 | |
|     uint8_t * data = NULL, * p = NULL;
 | |
| 
 | |
|     GREENTEA_SETUP( 180, "mbedtls_test" );
 | |
|     greentea_send_kv( "GO", " " );
 | |
| 
 | |
|     while ( 1 )
 | |
|     {
 | |
|         ret = 0;
 | |
|         test_info.failed = 0;
 | |
|         data_len = 0;
 | |
| 
 | |
|         data = receive_data( &data_len );
 | |
|         if ( data == NULL )
 | |
|             continue;
 | |
|         p = data;
 | |
| 
 | |
|         do
 | |
|         {
 | |
|             /* Read dependency count */
 | |
|             count = *p;
 | |
|             assert( count < data_len );
 | |
|             INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
 | |
|             ret = verify_dependencies( count, p );
 | |
|             if ( ret != DEPENDENCY_SUPPORTED )
 | |
|                 break;
 | |
| 
 | |
|             if ( count )
 | |
|                 INCR_ASSERT( p, data, data_len, count );
 | |
| 
 | |
|             /* Read function id */
 | |
|             function_id = *p;
 | |
|             INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
 | |
|             if ( ( ret = check_test( function_id ) ) != DISPATCH_TEST_SUCCESS )
 | |
|                 break;
 | |
| 
 | |
|             /* Read number of parameters */
 | |
|             count = *p;
 | |
|             INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) );
 | |
| 
 | |
|             /* Parse parameters if present */
 | |
|             if ( count )
 | |
|             {
 | |
|                 params = parse_parameters( count, p, data_len - ( p - data ), &ret );
 | |
|                 if ( ret )
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             ret = dispatch_test( function_id, params );
 | |
|         }
 | |
|         while ( 0 );
 | |
| 
 | |
|         if ( data )
 | |
|         {
 | |
|             free( data );
 | |
|             data = NULL;
 | |
|         }
 | |
| 
 | |
|         if ( params )
 | |
|         {
 | |
|             free( params );
 | |
|             params = NULL;
 | |
|         }
 | |
| 
 | |
|         if ( ret )
 | |
|             send_failure( ret );
 | |
|         else
 | |
|             send_status( test_info.failed );
 | |
|     }
 | |
|     return( 0 );
 | |
| }
 | |
| 
 |