Reduce code-size of mbedtls_x509_get_name()

Consider the following code-template:

   int beef();

   static int foo()
   {
        /* ... */
        ret = beef();
        if( ret != 0 )
           return( ret + HIGH_LEVEL );
        /* ... */
   }

   int bar()
   {
       /* ... */
       ret = foo();
       if( ret != 0 )
          ...
       /* ... */
   }

This leads to slightly larger code than expected, because when the
compiler inlines foo() into bar(), the sequence of return sequences
cannot be squashed, because compiler might not have knowledge that
the wrapping `ret + HIGH_LEVEL` of the return value of beef() doesn't
lead to foo() returning 0.

This can be avoided by performing error code wrapping in nested
functions calls at the top of the call chain.

This commit applies this slight optimization to mbedtls_x509_get_name().

It also moves various return statements into a single exit section,
again with the intend to save code.
This commit is contained in:
Hanno Becker 2019-02-20 11:30:29 +00:00
parent 3470d592ce
commit 30cb1ac23e

View File

@ -356,15 +356,17 @@ static int x509_get_attr_type_value( unsigned char **p,
int ret;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE );
if( ret != 0 )
goto exit;
end = *p + len;
ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID );
if( ret != 0 )
return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
goto exit;
oid->tag = MBEDTLS_ASN1_OID;
oid->p = *p;
@ -372,30 +374,30 @@ static int x509_get_attr_type_value( unsigned char **p,
if( *p == end )
{
return( MBEDTLS_ERR_X509_INVALID_NAME +
MBEDTLS_ERR_ASN1_OUT_OF_DATA );
ret = MBEDTLS_ERR_ASN1_OUT_OF_DATA;
goto exit;
}
if( !MBEDTLS_ASN1_IS_STRING_TAG( **p ) )
{
return( MBEDTLS_ERR_X509_INVALID_NAME +
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
ret = MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
goto exit;
}
val->tag = *(*p)++;
if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 )
return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
ret = mbedtls_asn1_get_len( p, end, &val->len );
if( ret != 0 )
goto exit;
val->p = *p;
*p += val->len;
if( *p != end )
{
return( MBEDTLS_ERR_X509_INVALID_NAME +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
}
return( 0 );
ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
exit:
return( ret );
}
/*
@ -438,12 +440,15 @@ static int x509_set_sequence_iterate( unsigned char **p,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SET );
if( ret != 0 )
return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
goto exit;
*end_set = *p + set_len;
}
return( x509_get_attr_type_value( p, *end_set, oid, val ) );
ret = x509_get_attr_type_value( p, *end_set, oid, val );
exit:
return( ret );
}
int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
@ -458,7 +463,7 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
ret = x509_set_sequence_iterate( p, &end_set, end,
&cur->oid, &cur->val );
if( ret != 0 )
return( ret );
return( ret + MBEDTLS_ERR_X509_INVALID_NAME );
if( *p != end_set )
cur->next_merged = 1;