Add support for const error description strings

Problem
-------
mbedtls_strerror is a utility function which converts an mbedTLS error code
into a human readable string. It requires the caller to allocate a buffer every
time an error code needs to be converted to a string. It is an overkill and a
waste of RAM for resource constrained microcontrollers - where the most common
use case is to use these strings for logging.

Solution
--------
The proposed commit adds two functions:

* const char * mbedtls_high_level_strerr( int error_code );
* const char * mbedtls_low_level_strerr( int error_code );

The above two functions convert the high level and low level parts of an mbedTLS
error code to human readable strings. They return a const pointer to an
unmodifiable string which is not supposed to be modified by the caller and only
to be used for logging purposes. The caller no longer needs to allocate a
buffer.

Backward Compatibility
----------------------
The proposed change is completely backward compatible as it does not change
the existing mbedtls_strerror function and ensures that it continues to behave
the same way.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
This commit is contained in:
Gaurav Aggarwal 2020-04-09 01:44:52 -07:00
parent 4500e83fe4
commit a9f64006ea
4 changed files with 553 additions and 681 deletions

View file

@ -127,6 +127,32 @@ extern "C" {
*/
void mbedtls_strerror( int errnum, char *buffer, size_t buflen );
/**
* \brief Translate high level part of a mbed TLS error code into a string
* representation.
*
* This function returns a const pointer to an un-modifiable string. The caller
* must not try to modify the string use it only for logging purposes.
*
* \param error_code error code
*
* \return The string representation of the error code.
*/
const char * mbedtls_high_level_strerr( int error_code );
/**
* \brief Translate low level part of a mbed TLS error code into a string
* representation.
*
* This function returns a const pointer to an un-modifiable string. The caller
* must not try to modify the string and use it only for logging purposes.
*
* \param error_code error code
*
* \return The string representation of the error code.
*/
const char * mbedtls_low_level_strerr( int error_code );
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -42,10 +42,66 @@
HEADER_INCLUDED
typedef struct mbedtls_error
{
int code; /* Error code. */
const char * description; /* Error description. */
} mbedtls_error_t;
static mbedtls_error_t high_level_errors[] =
{
HIGH_LEVEL_CODE_CHECKS
};
#define NUM_HIGH_LEVEL_ERRORS ( sizeof(high_level_errors)/sizeof(mbedtls_error_t) )
static mbedtls_error_t low_level_errors[] =
{
LOW_LEVEL_CODE_CHECKS
};
#define NUM_LOW_LEVEL_ERRORS ( sizeof(low_level_errors)/sizeof(mbedtls_error_t) )
const char * mbedtls_high_level_strerr( int error_code )
{
size_t i;
const char *error_description = NULL;
for(i = 0; i < NUM_HIGH_LEVEL_ERRORS; i++ )
{
if( high_level_errors[i].code == error_code )
{
error_description = high_level_errors[i].description;
break;
}
}
return error_description;
}
const char * mbedtls_low_level_strerr( int error_code )
{
size_t i;
const char *error_description = NULL;
for(i = 0; i < NUM_LOW_LEVEL_ERRORS; i++ )
{
if( low_level_errors[i].code == error_code )
{
error_description = low_level_errors[i].description;
break;
}
}
return error_description;
}
void mbedtls_strerror( int ret, char *buf, size_t buflen )
{
size_t len;
int use_ret;
const char * high_level_error_description = NULL;
const char * low_level_error_description = NULL;
if( buflen == 0 )
return;
@ -59,14 +115,18 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
{
use_ret = ret & 0xFF80;
// High level error codes
//
// BEGIN generated code
HIGH_LEVEL_CODE_CHECKS
// END generated code
// Translate high level error code.
high_level_error_description = mbedtls_high_level_strerr(use_ret);
if( strlen( buf ) == 0 )
if( high_level_error_description == NULL )
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
else
mbedtls_snprintf( buf, buflen, "%s", high_level_error_description );
// Early return in case of a fatal error - do not try to translate low
// level code.
if(use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE))
return;
}
use_ret = ret & ~0xFF80;
@ -90,16 +150,13 @@ HIGH_LEVEL_CODE_CHECKS
buflen -= len + 3;
}
// Low level error codes
//
// BEGIN generated code
LOW_LEVEL_CODE_CHECKS
// END generated code
// Translate low level error code.
low_level_error_description = mbedtls_low_level_strerr( use_ret );
if( strlen( buf ) != 0 )
return;
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
if( low_level_error_description == NULL )
mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
else
mbedtls_snprintf( buf, buflen, "%s", low_level_error_description );
}
#else /* MBEDTLS_ERROR_C */

View file

@ -125,7 +125,7 @@ foreach my $line (@matches)
{
$code_check = \$hl_code_check;
$old_define = \$hl_old_define;
$white_space = ' ';
$white_space = ' ';
}
if ($define_name ne ${$old_define})
@ -160,19 +160,7 @@ foreach my $line (@matches)
${$old_define} = $define_name;
}
if ($error_name eq "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE")
{
${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n".
"${white_space}\{\n".
"${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n".
"${white_space} return;\n".
"${white_space}}\n"
}
else
{
${$code_check} .= "${white_space}if( use_ret == -($error_name) )\n".
"${white_space} mbedtls_snprintf( buf, buflen, \"$module_name - $description\" );\n"
}
${$code_check} .= "${white_space}\{.code = -($error_name), .description=\"$module_name - $description\"},\n";
};
if ($ll_old_define ne "")