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.
diff --git a/library/x509.c b/library/x509.c
index 8f809ab..aeabdd3 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -356,15 +356,17 @@
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 @@
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 @@
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 @@
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;