Merge pull request #6407 from minosgalanakis/minos/6017_add_montgomery_constant_squared

Bignum: Added pre-calculation of Montgomery constants
diff --git a/ChangeLog.d/fix_x509_get_name_mem_leak.txt b/ChangeLog.d/fix_x509_get_name_mem_leak.txt
new file mode 100644
index 0000000..358d1af
--- /dev/null
+++ b/ChangeLog.d/fix_x509_get_name_mem_leak.txt
@@ -0,0 +1,4 @@
+Bugfix
+    * Fix memory leak in ssl_parse_certificate_request() caused by
+      mbedtls_x509_get_name() not freeing allocated objects in case of error.
+      Change mbedtls_x509_get_name() to clean up allocated objects on error.
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 9588ca4..a7af96a 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -1130,7 +1130,7 @@
  *
  * Enable support for PKCS#1 v1.5 encoding.
  *
- * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C
+ * Requires: MBEDTLS_RSA_C
  *
  * This enables support for PKCS#1 v1.5 operations.
  */
diff --git a/library/aria.c b/library/aria.c
index f78d289..924f952 100644
--- a/library/aria.c
+++ b/library/aria.c
@@ -888,15 +888,17 @@
 };
 #endif /* MBEDTLS_CIPHER_MODE_CFB */
 
-#define ARIA_SELF_TEST_IF_FAIL              \
-        {                                   \
-            if( verbose )                   \
-                mbedtls_printf( "failed\n" );       \
-            goto exit;                              \
-        } else {                            \
-            if( verbose )                   \
-                mbedtls_printf( "passed\n" );       \
-        }
+#define ARIA_SELF_TEST_ASSERT( cond )                   \
+        do {                                            \
+            if( cond ) {                                \
+                if( verbose )                           \
+                    mbedtls_printf( "failed\n" );       \
+                goto exit;                              \
+            } else {                                    \
+                if( verbose )                           \
+                    mbedtls_printf( "passed\n" );       \
+            }                                           \
+        } while( 0 )
 
 /*
  * Checkup routine
@@ -930,16 +932,18 @@
             mbedtls_printf( "  ARIA-ECB-%d (enc): ", 128 + 64 * i );
         mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i );
         mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk );
-        if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 )
-            ARIA_SELF_TEST_IF_FAIL;
+        ARIA_SELF_TEST_ASSERT(
+                memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE )
+                != 0 );
 
         /* test ECB decryption */
         if( verbose )
             mbedtls_printf( "  ARIA-ECB-%d (dec): ", 128 + 64 * i );
         mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i );
         mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk );
-        if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 )
-            ARIA_SELF_TEST_IF_FAIL;
+        ARIA_SELF_TEST_ASSERT(
+                memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE )
+                != 0 );
     }
     if( verbose )
         mbedtls_printf( "\n" );
@@ -958,8 +962,8 @@
         memset( buf, 0x55, sizeof( buf ) );
         mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
             aria_test2_pt, buf );
-        if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 )
-            ARIA_SELF_TEST_IF_FAIL;
+        ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_cbc_ct[i], 48 )
+                != 0 );
 
         /* Test CBC decryption */
         if( verbose )
@@ -969,8 +973,7 @@
         memset( buf, 0xAA, sizeof( buf ) );
         mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
             aria_test2_cbc_ct[i], buf );
-        if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
-            ARIA_SELF_TEST_IF_FAIL;
+        ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_pt, 48 ) != 0 );
     }
     if( verbose )
         mbedtls_printf( "\n" );
@@ -989,8 +992,7 @@
         j = 0;
         mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
             aria_test2_pt, buf );
-        if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 )
-            ARIA_SELF_TEST_IF_FAIL;
+        ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 );
 
         /* Test CFB decryption */
         if( verbose )
@@ -1001,8 +1003,7 @@
         j = 0;
         mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
             iv, aria_test2_cfb_ct[i], buf );
-        if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
-            ARIA_SELF_TEST_IF_FAIL;
+        ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_pt, 48 ) != 0 );
     }
     if( verbose )
         mbedtls_printf( "\n" );
@@ -1020,8 +1021,7 @@
         j = 0;
         mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
             aria_test2_pt, buf );
-        if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 )
-            ARIA_SELF_TEST_IF_FAIL;
+        ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 );
 
         /* Test CTR decryption */
         if( verbose )
@@ -1032,8 +1032,7 @@
         j = 0;
         mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
             aria_test2_ctr_ct[i], buf );
-        if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
-            ARIA_SELF_TEST_IF_FAIL;
+        ARIA_SELF_TEST_ASSERT( memcmp( buf, aria_test2_pt, 48 ) != 0 );
     }
     if( verbose )
         mbedtls_printf( "\n" );
diff --git a/library/asn1write.c b/library/asn1write.c
index f1adcb5..98c591d 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -72,9 +72,11 @@
         return( 4 );
     }
 
+    int len_is_valid = 1;
 #if SIZE_MAX > 0xFFFFFFFF
-    if( len <= 0xFFFFFFFF )
+    len_is_valid = ( len <= 0xFFFFFFFF );
 #endif
+    if( len_is_valid )
     {
         if( *p - start < 5 )
             return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
@@ -87,9 +89,7 @@
         return( 5 );
     }
 
-#if SIZE_MAX > 0xFFFFFFFF
     return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
-#endif
 }
 
 int mbedtls_asn1_write_tag( unsigned char **p, const unsigned char *start, unsigned char tag )
diff --git a/library/ecdh.c b/library/ecdh.c
index 35ab1b7..c9c2e06 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -71,10 +71,12 @@
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    /* If multiplication is in progress, we already generated a privkey */
+    int restarting = 0;
 #if defined(MBEDTLS_ECP_RESTARTABLE)
-    if( rs_ctx == NULL || rs_ctx->rsm == NULL )
+    restarting = ( rs_ctx != NULL && rs_ctx->rsm != NULL );
 #endif
+    /* If multiplication is in progress, we already generated a privkey */
+    if( !restarting )
         MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
 
     MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G,
diff --git a/library/ecp.c b/library/ecp.c
index ee6c24a..5c597d5 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -2279,12 +2279,14 @@
         mbedtls_free( T );
     }
 
-    /* don't free R while in progress in case R == P */
-#if defined(MBEDTLS_ECP_RESTARTABLE)
-    if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
-#endif
     /* prevent caller from using invalid value */
-    if( ret != 0 )
+    int should_free_R = ( ret != 0 );
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    /* don't free R while in progress in case R == P */
+    if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+        should_free_R = 0;
+#endif
+    if( should_free_R )
         mbedtls_ecp_point_free( R );
 
     ECP_RS_LEAVE( rsm );
@@ -2529,10 +2531,12 @@
         MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
 #endif /* MBEDTLS_ECP_INTERNAL_ALT */
 
+    int restarting = 0;
 #if defined(MBEDTLS_ECP_RESTARTABLE)
-    /* skip argument check when restarting */
-    if( rs_ctx == NULL || rs_ctx->rsm == NULL )
+    restarting = ( rs_ctx != NULL && rs_ctx->rsm != NULL );
 #endif
+    /* skip argument check when restarting */
+    if( !restarting )
     {
         /* check_privkey is free */
         MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_CHK );
diff --git a/library/sha256.c b/library/sha256.c
index 0e9c1a1..1a9a855 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -655,9 +655,11 @@
     MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
     MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
 
+    int truncated = 0;
 #if defined(MBEDTLS_SHA224_C)
-    if( ctx->is224 == 0 )
+    truncated = ctx->is224;
 #endif
+    if( !truncated )
         MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
 
     return( 0 );
diff --git a/library/sha512.c b/library/sha512.c
index aa6f06a..92ada8c 100644
--- a/library/sha512.c
+++ b/library/sha512.c
@@ -810,9 +810,11 @@
     sha512_put_uint64_be( ctx->state[4], output, 32 );
     sha512_put_uint64_be( ctx->state[5], output, 40 );
 
+    int truncated = 0;
 #if defined(MBEDTLS_SHA384_C)
-    if( ctx->is384 == 0 )
+    truncated = ctx->is384;
 #endif
+    if( !truncated )
     {
         sha512_put_uint64_be( ctx->state[6], output, 48 );
         sha512_put_uint64_be( ctx->state[7], output, 56 );
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 01f1b68..d9c6781 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -370,9 +370,11 @@
     /*
      * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
      */
+    int renegotiating = 0;
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
-    if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
+    renegotiating = ( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE );
 #endif
+    if( !renegotiating )
     {
         MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) );
         MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
@@ -811,9 +813,12 @@
      * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
      * generate and include a Session ID in the TLS ClientHello."
      */
+        int renegotiating = 0;
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
-        if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
+        if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
+            renegotiating = 1;
 #endif
+        if( !renegotiating )
         {
             if( ( session_negotiate->ticket != NULL ) &&
                 ( session_negotiate->ticket_len != 0 ) )
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 4f998b4..4cd4107 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -3847,8 +3847,8 @@
 
             if( ssl_record_is_in_progress( ssl ) == 0 )
             {
+                int dtls_have_buffered = 0;
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
-                int have_buffered = 0;
 
                 /* We only check for buffered messages if the
                  * current datagram is fully consumed. */
@@ -3856,11 +3856,11 @@
                     ssl_next_record_is_in_datagram( ssl ) == 0 )
                 {
                     if( ssl_load_buffered_message( ssl ) == 0 )
-                        have_buffered = 1;
+                        dtls_have_buffered = 1;
                 }
 
-                if( have_buffered == 0 )
 #endif /* MBEDTLS_SSL_PROTO_DTLS */
+                if( dtls_have_buffered == 0 )
                 {
                     ret = ssl_get_next_record( ssl );
                     if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING )
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 63a433d..0759ef9 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1224,9 +1224,11 @@
 #endif
 
 #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+    int free_cli_id = 1;
 #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
-    if( partial == 0 )
+    free_cli_id = ( partial == 0 );
 #endif
+    if( free_cli_id )
     {
         mbedtls_free( ssl->cli_id );
         ssl->cli_id = NULL;
@@ -7714,11 +7716,16 @@
          *   sequence number).
          */
         transform->ivlen = 12;
+
+        int is_chachapoly = 0;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-        if( key_type == PSA_KEY_TYPE_CHACHA20 )
+        is_chachapoly = ( key_type == PSA_KEY_TYPE_CHACHA20 );
 #else
-        if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CHACHAPOLY )
+        is_chachapoly = ( mbedtls_cipher_info_get_mode( cipher_info )
+                == MBEDTLS_MODE_CHACHAPOLY );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+        if( is_chachapoly )
             transform->fixed_ivlen = 12;
         else
             transform->fixed_ivlen = 4;
diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c
index 72c77bb..d82918f 100644
--- a/library/ssl_tls12_client.c
+++ b/library/ssl_tls12_client.c
@@ -2444,9 +2444,11 @@
 
         if( ret != 0 )
         {
+            int send_alert_msg = 1;
 #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
-            if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
+            send_alert_msg = ( ret != MBEDTLS_ERR_ECP_IN_PROGRESS );
 #endif
+            if( send_alert_msg )
                 mbedtls_ssl_send_alert_message(
                     ssl,
                     MBEDTLS_SSL_ALERT_LEVEL_FATAL,
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 66c61a3..71f703c 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -708,11 +708,13 @@
 #endif
         list = ssl->conf->key_cert;
 
+    int pk_alg_is_none = 0;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    if( pk_alg == PSA_ALG_NONE )
+    pk_alg_is_none = ( pk_alg == PSA_ALG_NONE );
 #else
-    if( pk_alg == MBEDTLS_PK_NONE )
+    pk_alg_is_none = ( pk_alg == MBEDTLS_PK_NONE );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
+    if( pk_alg_is_none )
         return( 0 );
 
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite requires certificate" ) );
@@ -729,18 +731,21 @@
         MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
                           cur->cert );
 
+        int key_type_matches = 0;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
 #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
-        if( ( ssl->conf->f_async_sign_start == NULL &&
-              ssl->conf->f_async_decrypt_start == NULL &&
-              ! mbedtls_pk_can_do_ext( cur->key, pk_alg, pk_usage ) ) ||
-            ! mbedtls_pk_can_do_ext( &cur->cert->pk, pk_alg, pk_usage ) )
+        key_type_matches = ( ( ssl->conf->f_async_sign_start != NULL ||
+                    ssl->conf->f_async_decrypt_start != NULL ||
+                    mbedtls_pk_can_do_ext( cur->key, pk_alg, pk_usage ) ) &&
+                mbedtls_pk_can_do_ext( &cur->cert->pk, pk_alg, pk_usage ) );
 #else
-        if( ! mbedtls_pk_can_do_ext( cur->key, pk_alg, pk_usage ) )
+        key_type_matches = (
+                mbedtls_pk_can_do_ext( cur->key, pk_alg, pk_usage ) );
 #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
 #else
-        if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) )
+        key_type_matches = mbedtls_pk_can_do( &cur->cert->pk, pk_alg );
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
+        if( !key_type_matches )
         {
             MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
             continue;
@@ -917,6 +922,8 @@
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
 
+    int renegotiating;
+
 #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
 read_record_header:
 #endif
@@ -925,9 +932,11 @@
      * otherwise read it ourselves manually in order to support SSLv2
      * ClientHello, which doesn't use the same record layer format.
      */
+    renegotiating = 0;
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
-    if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
+    renegotiating = ( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE );
 #endif
+    if( !renegotiating )
     {
         if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 )
         {
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 8b9ac34..741ead0 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -674,11 +674,13 @@
 
     *olen = 0;
 
+    int not_using_psk = 0;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
-    if( mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
+    not_using_psk = ( mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) );
 #else
-    if( ssl->handshake->psk == NULL )
+    not_using_psk = ( ssl->handshake->psk == NULL );
 #endif
+    if( not_using_psk )
     {
         /* We shouldn't have called this extension writer unless we've
          * chosen to use a PSK. */
diff --git a/library/x509.c b/library/x509.c
index ca2e907..c5b0161 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -459,6 +459,11 @@
  * For the general case we still use a flat list, but we mark elements of the
  * same set so that they are "merged" together in the functions that consume
  * this list, eg mbedtls_x509_dn_gets().
+ *
+ * On success, this function may allocate a linked list starting at cur->next
+ * that must later be free'd by the caller using mbedtls_free(). In error
+ * cases, this function frees all allocated memory internally and the caller
+ * has no freeing responsibilities.
  */
 int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
                    mbedtls_x509_name *cur )
@@ -466,6 +471,8 @@
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t set_len;
     const unsigned char *end_set;
+    mbedtls_x509_name *head = cur;
+    mbedtls_x509_name *prev, *allocated;
 
     /* don't use recursion, we'd risk stack overflow if not optimized */
     while( 1 )
@@ -475,14 +482,17 @@
          */
         if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
-            return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) );
+        {
+            ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret );
+            goto error;
+        }
 
         end_set  = *p + set_len;
 
         while( 1 )
         {
             if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
-                return( ret );
+                goto error;
 
             if( *p == end_set )
                 break;
@@ -493,7 +503,10 @@
             cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
 
             if( cur->next == NULL )
-                return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+            {
+                ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
+                goto error;
+            }
 
             cur = cur->next;
         }
@@ -507,10 +520,30 @@
         cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
 
         if( cur->next == NULL )
-            return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+        {
+            ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
+            goto error;
+        }
 
         cur = cur->next;
     }
+
+error:
+    /* Skip the first element as we did not allocate it */
+    allocated = head->next;
+
+    while( allocated != NULL )
+    {
+        prev = allocated;
+        allocated = allocated->next;
+
+        mbedtls_platform_zeroize( prev, sizeof( *prev ) );
+        mbedtls_free( prev );
+    }
+
+    mbedtls_platform_zeroize( head, sizeof( *head ) );
+
+    return( ret );
 }
 
 static int x509_parse_int( unsigned char **p, size_t n, int *res )
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 556ecb9..80862f9 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1731,15 +1731,17 @@
             if( ret != 0 )
                 break;
         }
-        if( ret == 0 )
 #endif /* MBEDTLS_PEM_PARSE_C */
-        for( i = 0; mbedtls_test_cas_der[i] != NULL; i++ )
+        if( ret == 0 )
         {
-            ret = mbedtls_x509_crt_parse_der( &cacert,
-                         (const unsigned char *) mbedtls_test_cas_der[i],
-                         mbedtls_test_cas_der_len[i] );
-            if( ret != 0 )
-                break;
+            for( i = 0; mbedtls_test_cas_der[i] != NULL; i++ )
+            {
+                ret = mbedtls_x509_crt_parse_der( &cacert,
+                             (const unsigned char *) mbedtls_test_cas_der[i],
+                             mbedtls_test_cas_der_len[i] );
+                if( ret != 0 )
+                    break;
+            }
         }
     }
     if( ret < 0 )
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 67be9bf..9ec2f87 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -2613,15 +2613,17 @@
             if( ret != 0 )
                 break;
         }
-        if( ret == 0 )
 #endif /* MBEDTLS_PEM_PARSE_C */
-        for( i = 0; mbedtls_test_cas_der[i] != NULL; i++ )
+        if( ret == 0 )
         {
-            ret = mbedtls_x509_crt_parse_der( &cacert,
-                         (const unsigned char *) mbedtls_test_cas_der[i],
-                         mbedtls_test_cas_der_len[i] );
-            if( ret != 0 )
-                break;
+            for( i = 0; mbedtls_test_cas_der[i] != NULL; i++ )
+            {
+                ret = mbedtls_x509_crt_parse_der( &cacert,
+                             (const unsigned char *) mbedtls_test_cas_der[i],
+                             mbedtls_test_cas_der_len[i] );
+                if( ret != 0 )
+                    break;
+            }
         }
     }
     if( ret < 0 )
diff --git a/tests/suites/test_suite_psa_crypto_storage_format.function b/tests/suites/test_suite_psa_crypto_storage_format.function
index c52dae1..1fd267a 100644
--- a/tests/suites/test_suite_psa_crypto_storage_format.function
+++ b/tests/suites/test_suite_psa_crypto_storage_format.function
@@ -84,17 +84,21 @@
  * also be built-in. */
 static int is_builtin_calling_md( psa_algorithm_t alg )
 {
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN)
-    if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
-        return( 1 );
-#endif
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS)
     if( PSA_ALG_IS_RSA_PSS( alg ) )
+#if defined(MBEDTLS_MD_C)
         return( 1 );
+#else
+        return( 0 );
+#endif
 #endif
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP)
     if( PSA_ALG_IS_RSA_OAEP( alg ) )
+#if defined(MBEDTLS_MD_C)
         return( 1 );
+#else
+        return( 0 );
+#endif
 #endif
 #if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
     if( PSA_ALG_IS_DETERMINISTIC_ECDSA( alg ) )
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 6263fba..8dd3379 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -415,6 +415,46 @@
 X509 Get Next DN #4 Consecutive Multivalue RDNs
 mbedtls_x509_dn_get_next:"C=NL, O=PolarSSL, title=Example, CN=PolarSSL Server 1":0x05:"C title":2:"C=NL + O=PolarSSL, title=Example + CN=PolarSSL Server 1"
 
+# Parse the following valid DN:
+#
+# 31 0B <- Set of
+#     30 09 <- Sequence of
+#         06 03 55 04 06 <- OID 2.5.4.6 countryName (C)
+#         13 02 4E 4C <- PrintableString "NL"
+# 31 11 <- Set of
+#     30 0F <- Sequence of
+#         06 03 55 04 0A <- OID 2.5.4.10 organizationName (O)
+#         0C 08 50 6F 6C 61 72 53 53 4C <- UTF8String "PolarSSL"
+# 31 19 <- Set of
+#     30 17 <- Sequence of
+#         06 03 55 04 03 <- OID 2.5.4.3 commonName (CN)
+#         0C 10 50 6F 6C 61 72 53 53 4C 20 54 65 73 74 20 43 41 <- UTF8String "PolarSSL Test CA"
+#
+X509 Get Name Valid DN
+mbedtls_x509_get_name:"310B3009060355040613024E4C3111300F060355040A0C08506F6C617253534C3119301706035504030C10506F6C617253534C2054657374204341":0
+
+# Parse the following corrupted DN:
+#
+# 31 0B <- Set of
+#     30 09 <- Sequence of
+#         06 03 55 04 06 <- OID 2.5.4.6 countryName (C)
+#         13 02 4E 4C <- PrintableString "NL"
+# 31 11 <- Set of
+#     30 0F <- Sequence of
+#         06 03 55 04 0A <- OID 2.5.4.10 organizationName (O)
+#         0C 08 50 6F 6C 61 72 53 53 4C <- UTF8String "PolarSSL"
+# 30 19 <- Sequence of (corrupted)
+#     30 17 <- Sequence of
+#         06 03 55 04 03 <- OID 2.5.4.3 commonName (CN)
+#         0C 10 50 6F 6C 61 72 53 53 4C 20 54 65 73 74 20 43 41 <- UTF8String "PolarSSL Test CA"
+#
+# The third 'Set of' is corrupted to instead be a 'Sequence of', causing an
+# error and forcing mbedtls_x509_get_name() to clean up the names it has
+# already allocated.
+#
+X509 Get Name Corrupted DN Mem Leak
+mbedtls_x509_get_name:"310B3009060355040613024E4C3111300F060355040A0C08506F6C617253534C3019301706035504030C10506F6C617253534C2054657374204341":MBEDTLS_ERR_X509_INVALID_NAME + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
 X509 Time Expired #1
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAVE_TIME_DATE:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA
 mbedtls_x509_time_is_past:"data_files/server1.crt":"valid_from":1
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 60e703a..a3606f2 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -818,6 +818,41 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
+void mbedtls_x509_get_name( char * rdn_sequence, int exp_ret )
+{
+    unsigned char *name;
+    unsigned char *p;
+    size_t name_len;
+    mbedtls_x509_name head;
+    mbedtls_x509_name *allocated, *prev;
+    int ret;
+
+    memset( &head, 0, sizeof( head ) );
+
+    name = mbedtls_test_unhexify_alloc( rdn_sequence, &name_len );
+    p = name;
+
+    ret = mbedtls_x509_get_name( &p, ( name + name_len ), &head );
+    if( ret == 0 )
+    {
+        allocated = head.next;
+
+        while( allocated != NULL )
+        {
+            prev = allocated;
+            allocated = allocated->next;
+
+            mbedtls_free( prev );
+        }
+    }
+
+    TEST_EQUAL( ret, exp_ret );
+
+    mbedtls_free( name );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_X509_CREATE_C:MBEDTLS_X509_USE_C:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
 void mbedtls_x509_dn_get_next( char * name_str, int next_merged, char * expected_oids, int exp_count, char * exp_dn_gets )
 {