From 30cb1ac23eac08bd3dafc331262dfe589ecf28b8 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 20 Feb 2019 11:30:29 +0000 Subject: [PATCH] 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. --- library/x509.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/library/x509.c b/library/x509.c index 8f809ab55..aeabdd3fa 100644 --- a/library/x509.c +++ b/library/x509.c @@ -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;