Merge pull request #7022 from daverodgman/3DES-warning

Improve warnings for DES/3DES
diff --git a/.travis.yml b/.travis.yml
index eaf817a..54df776 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -53,7 +53,7 @@
         - tests/scripts/test_psa_constant_names.py
         - tests/ssl-opt.sh
         # Modern OpenSSL does not support fixed ECDH or null ciphers.
-        - tests/compat.sh -p OpenSSL -e 'NULL\|ECDH-'
+        - tests/compat.sh -p OpenSSL -e 'NULL\|ECDH_'
         - tests/scripts/travis-log-failure.sh
         # GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it.
         - tests/compat.sh -p GnuTLS -e 'CAMELLIA'
diff --git a/ChangeLog.d/csr_v3_extensions.txt b/ChangeLog.d/csr_v3_extensions.txt
new file mode 100644
index 0000000..9274017
--- /dev/null
+++ b/ChangeLog.d/csr_v3_extensions.txt
@@ -0,0 +1,3 @@
+Features
+   * Add parsing of V3 extensions (key usage, Netscape cert-type,
+     Subject Alternative Names) in x509 Certificate Sign Requests.
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index 52fadad..aa1cd08 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -148,7 +148,7 @@
 
 /*
  * X.509 v3 Key Usage Extension flags
- * Reminder: update x509_info_key_usage() when adding new flags.
+ * Reminder: update mbedtls_x509_info_key_usage() when adding new flags.
  */
 #define MBEDTLS_X509_KU_DIGITAL_SIGNATURE            (0x80)  /* bit 0 */
 #define MBEDTLS_X509_KU_NON_REPUDIATION              (0x40)  /* bit 1 */
@@ -250,6 +250,56 @@
 }
 mbedtls_x509_time;
 
+/**
+ * From RFC 5280 section 4.2.1.6:
+ * OtherName ::= SEQUENCE {
+ *      type-id    OBJECT IDENTIFIER,
+ *      value      [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * Future versions of the library may add new fields to this structure or
+ * to its embedded union and structure.
+ */
+typedef struct mbedtls_x509_san_other_name {
+    /**
+     * The type_id is an OID as defined in RFC 5280.
+     * To check the value of the type id, you should use
+     * \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
+     */
+    mbedtls_x509_buf type_id;                   /**< The type id. */
+    union {
+        /**
+         * From RFC 4108 section 5:
+         * HardwareModuleName ::= SEQUENCE {
+         *                         hwType OBJECT IDENTIFIER,
+         *                         hwSerialNum OCTET STRING }
+         */
+        struct {
+            mbedtls_x509_buf oid;               /**< The object identifier. */
+            mbedtls_x509_buf val;               /**< The named value. */
+        }
+        hardware_module_name;
+    }
+    value;
+}
+mbedtls_x509_san_other_name;
+
+/**
+ * A structure for holding the parsed Subject Alternative Name,
+ * according to type.
+ *
+ * Future versions of the library may add new fields to this structure or
+ * to its embedded union and structure.
+ */
+typedef struct mbedtls_x509_subject_alternative_name {
+    int type;                              /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
+    union {
+        mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */
+        mbedtls_x509_buf   unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */
+    }
+    san; /**< A union of the supported SAN types */
+}
+mbedtls_x509_subject_alternative_name;
+
 /** \} name Structures for parsing X.509 certificates, CRLs and CSRs */
 
 /**
@@ -326,6 +376,36 @@
  */
 int mbedtls_x509_time_is_future(const mbedtls_x509_time *from);
 
+/**
+ * \brief          This function parses an item in the SubjectAlternativeNames
+ *                 extension.
+ *
+ * \param san_buf  The buffer holding the raw data item of the subject
+ *                 alternative name.
+ * \param san      The target structure to populate with the parsed presentation
+ *                 of the subject alternative name encoded in \p san_raw.
+ *
+ * \note           Only "dnsName" and "otherName" of type hardware_module_name
+ *                 as defined in RFC 4180 is supported.
+ *
+ * \note           This function should be called on a single raw data of
+ *                 subject alternative name. For example, after successful
+ *                 certificate parsing, one must iterate on every item in the
+ *                 \p crt->subject_alt_names sequence, and pass it to
+ *                 this function.
+ *
+ * \warning        The target structure contains pointers to the raw data of the
+ *                 parsed certificate, and its lifetime is restricted by the
+ *                 lifetime of the certificate.
+ *
+ * \return         \c 0 on success
+ * \return         #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported
+ *                 SAN type.
+ * \return         Another negative value for any other failure.
+ */
+int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
+                                        mbedtls_x509_subject_alternative_name *san);
+
 /** \} addtogroup x509_module */
 
 /*
@@ -370,6 +450,23 @@
 int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start,
                            const char *oid, size_t oid_len,
                            unsigned char *sig, size_t size);
+int mbedtls_x509_get_ns_cert_type(unsigned char **p,
+                                  const unsigned char *end,
+                                  unsigned char *ns_cert_type);
+int mbedtls_x509_get_key_usage(unsigned char **p,
+                               const unsigned char *end,
+                               unsigned int *key_usage);
+int mbedtls_x509_get_subject_alt_name(unsigned char **p,
+                                      const unsigned char *end,
+                                      mbedtls_x509_sequence *subject_alt_name);
+int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
+                                       const mbedtls_x509_sequence
+                                       *subject_alt_name,
+                                       const char *prefix);
+int mbedtls_x509_info_cert_type(char **buf, size_t *size,
+                                unsigned char ns_cert_type);
+int mbedtls_x509_info_key_usage(char **buf, size_t *size,
+                                unsigned int key_usage);
 
 #define MBEDTLS_X509_SAFE_SNPRINTF                          \
     do {                                                    \
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 7c3a625..187e60a 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -103,56 +103,6 @@
 mbedtls_x509_crt;
 
 /**
- * From RFC 5280 section 4.2.1.6:
- * OtherName ::= SEQUENCE {
- *      type-id    OBJECT IDENTIFIER,
- *      value      [0] EXPLICIT ANY DEFINED BY type-id }
- *
- * Future versions of the library may add new fields to this structure or
- * to its embedded union and structure.
- */
-typedef struct mbedtls_x509_san_other_name {
-    /**
-     * The type_id is an OID as defined in RFC 5280.
-     * To check the value of the type id, you should use
-     * \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
-     */
-    mbedtls_x509_buf type_id;                   /**< The type id. */
-    union {
-        /**
-         * From RFC 4108 section 5:
-         * HardwareModuleName ::= SEQUENCE {
-         *                         hwType OBJECT IDENTIFIER,
-         *                         hwSerialNum OCTET STRING }
-         */
-        struct {
-            mbedtls_x509_buf oid;               /**< The object identifier. */
-            mbedtls_x509_buf val;               /**< The named value. */
-        }
-        hardware_module_name;
-    }
-    value;
-}
-mbedtls_x509_san_other_name;
-
-/**
- * A structure for holding the parsed Subject Alternative Name,
- * according to type.
- *
- * Future versions of the library may add new fields to this structure or
- * to its embedded union and structure.
- */
-typedef struct mbedtls_x509_subject_alternative_name {
-    int type;                              /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
-    union {
-        mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */
-        mbedtls_x509_buf   unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */
-    }
-    san; /**< A union of the supported SAN types */
-}
-mbedtls_x509_subject_alternative_name;
-
-/**
  * Build flag from an algorithm/curve identifier (pk, md, ecp)
  * Since 0 is always XXX_NONE, ignore it.
  */
@@ -590,36 +540,6 @@
 int mbedtls_x509_crt_parse_path(mbedtls_x509_crt *chain, const char *path);
 
 #endif /* MBEDTLS_FS_IO */
-/**
- * \brief          This function parses an item in the SubjectAlternativeNames
- *                 extension.
- *
- * \param san_buf  The buffer holding the raw data item of the subject
- *                 alternative name.
- * \param san      The target structure to populate with the parsed presentation
- *                 of the subject alternative name encoded in \p san_raw.
- *
- * \note           Only "dnsName" and "otherName" of type hardware_module_name
- *                 as defined in RFC 4180 is supported.
- *
- * \note           This function should be called on a single raw data of
- *                 subject alternative name. For example, after successful
- *                 certificate parsing, one must iterate on every item in the
- *                 \p crt->subject_alt_names sequence, and pass it to
- *                 this function.
- *
- * \warning        The target structure contains pointers to the raw data of the
- *                 parsed certificate, and its lifetime is restricted by the
- *                 lifetime of the certificate.
- *
- * \return         \c 0 on success
- * \return         #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported
- *                 SAN type.
- * \return         Another negative value for any other failure.
- */
-int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
-                                        mbedtls_x509_subject_alternative_name *san);
-
 #if !defined(MBEDTLS_X509_REMOVE_INFO)
 /**
  * \brief          Returns an informational string about the
diff --git a/include/mbedtls/x509_csr.h b/include/mbedtls/x509_csr.h
index 50998c4..0c204be 100644
--- a/include/mbedtls/x509_csr.h
+++ b/include/mbedtls/x509_csr.h
@@ -58,6 +58,12 @@
 
     mbedtls_pk_context pk;          /**< Container for the public key context. */
 
+    unsigned int key_usage;     /**< Optional key usage extension value: See the values in x509.h */
+    unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */
+    mbedtls_x509_sequence subject_alt_names;    /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */
+
+    int MBEDTLS_PRIVATE(ext_types);              /**< Bit string containing detected and parsed extensions */
+
     mbedtls_x509_buf sig_oid;
     mbedtls_x509_buf MBEDTLS_PRIVATE(sig);
     mbedtls_md_type_t MBEDTLS_PRIVATE(sig_md);       /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
diff --git a/library/ccm.c b/library/ccm.c
index 0b02d77..36c999e 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -659,7 +659,7 @@
     mbedtls_ccm_init(&ctx);
 
     if (mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key_test_data,
-                           8 * sizeof key_test_data) != 0) {
+                           8 * sizeof(key_test_data)) != 0) {
         if (verbose != 0) {
             mbedtls_printf("  CCM: setup failed");
         }
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 727283f..7987c3f 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -4507,7 +4507,7 @@
     defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
 /*
  * Create an MPI from embedded constants
- * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
+ * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint))
  */
 static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len)
 {
@@ -5370,7 +5370,7 @@
     if (M.n > p_limbs + adjust) {
         M.n = p_limbs + adjust;
     }
-    memset(Mp, 0, sizeof Mp);
+    memset(Mp, 0, sizeof(Mp));
     memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
     if (shift != 0) {
         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
@@ -5396,7 +5396,7 @@
     if (M.n > p_limbs + adjust) {
         M.n = p_limbs + adjust;
     }
-    memset(Mp, 0, sizeof Mp);
+    memset(Mp, 0, sizeof(Mp));
     memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
     if (shift != 0) {
         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
diff --git a/library/entropy.c b/library/entropy.c
index 7e25f28..e55410c 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -677,7 +677,7 @@
         goto cleanup;
     }
 
-    if ((ret = mbedtls_entropy_update_manual(&ctx, buf, sizeof buf)) != 0) {
+    if ((ret = mbedtls_entropy_update_manual(&ctx, buf, sizeof(buf))) != 0) {
         goto cleanup;
     }
 
diff --git a/library/ripemd160.c b/library/ripemd160.c
index eed664f..ba97c1f 100644
--- a/library/ripemd160.c
+++ b/library/ripemd160.c
@@ -456,7 +456,7 @@
     int i, ret = 0;
     unsigned char output[20];
 
-    memset(output, 0, sizeof output);
+    memset(output, 0, sizeof(output));
 
     for (i = 0; i < TESTS; i++) {
         if (verbose != 0) {
diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
index ecfdab3..b92f12e 100644
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -644,7 +644,24 @@
     return 0;
 }
 
-int mbedtls_ssl_tls13_key_schedule_stage_application(mbedtls_ssl_context *ssl)
+/**
+ * \brief Transition into application stage of TLS 1.3 key schedule.
+ *
+ *        The TLS 1.3 key schedule can be viewed as a simple state machine
+ *        with states Initial -> Early -> Handshake -> Application, and
+ *        this function represents the Handshake -> Application transition.
+ *
+ *        In the handshake stage, ssl_tls13_generate_application_keys()
+ *        can be used to derive the handshake traffic keys.
+ *
+ * \param ssl  The SSL context to operate on. This must be in key schedule
+ *             stage \c Handshake.
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_key_schedule_stage_application(mbedtls_ssl_context *ssl)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
@@ -1282,10 +1299,25 @@
     return 0;
 }
 
-/* mbedtls_ssl_tls13_generate_handshake_keys() generates keys necessary for
- * protecting the handshake messages, as described in Section 7 of TLS 1.3. */
-int mbedtls_ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl,
-                                              mbedtls_ssl_key_set *traffic_keys)
+/**
+ * \brief Compute TLS 1.3 handshake traffic keys.
+ *
+ *        ssl_tls13_generate_handshake_keys() generates keys necessary for
+ *        protecting the handshake messages, as described in Section 7 of
+ *        RFC 8446.
+ *
+ * \param ssl  The SSL context to operate on. This must be in
+ *             key schedule stage \c Handshake, see
+ *             ssl_tls13_key_schedule_stage_handshake().
+ * \param traffic_keys The address at which to store the handshake traffic
+ *                     keys. This must be writable but may be uninitialized.
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl,
+                                             mbedtls_ssl_key_set *traffic_keys)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_md_type_t md_type;
@@ -1300,7 +1332,7 @@
     const mbedtls_ssl_ciphersuite_t *ciphersuite_info = handshake->ciphersuite_info;
     mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets = &handshake->tls13_hs_secrets;
 
-    MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_tls13_generate_handshake_keys"));
+    MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_handshake_keys"));
 
     ret = ssl_tls13_get_cipher_key_info(ciphersuite_info, &key_len, &iv_len);
     if (ret != 0) {
@@ -1386,14 +1418,31 @@
                           traffic_keys->server_write_iv,
                           traffic_keys->iv_len);
 
-    MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_tls13_generate_handshake_keys"));
+    MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_generate_handshake_keys"));
 
 exit:
 
     return ret;
 }
 
-int mbedtls_ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl)
+/**
+ * \brief Transition into handshake stage of TLS 1.3 key schedule.
+ *
+ *        The TLS 1.3 key schedule can be viewed as a simple state machine
+ *        with states Initial -> Early -> Handshake -> Application, and
+ *        this function represents the Early -> Handshake transition.
+ *
+ *        In the handshake stage, ssl_tls13_generate_handshake_keys()
+ *        can be used to derive the handshake traffic keys.
+ *
+ * \param ssl  The SSL context to operate on. This must be in key schedule
+ *             stage \c Early.
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
+ */
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
@@ -1479,10 +1528,24 @@
     return ret;
 }
 
-/* Generate application traffic keys since any records following a 1-RTT Finished message
- * MUST be encrypted under the application traffic key.
+/**
+ * \brief Compute TLS 1.3 application traffic keys.
+ *
+ *        ssl_tls13_generate_application_keys() generates application traffic
+ *        keys, since any record following a 1-RTT Finished message MUST be
+ *        encrypted under the application traffic key.
+ *
+ * \param ssl  The SSL context to operate on. This must be in
+ *             key schedule stage \c Application, see
+ *             ssl_tls13_key_schedule_stage_application().
+ * \param traffic_keys The address at which to store the application traffic
+ *                     keys. This must be writable but may be uninitialized.
+ *
+ * \returns    \c 0 on success.
+ * \returns    A negative error code on failure.
  */
-int mbedtls_ssl_tls13_generate_application_keys(
+MBEDTLS_CHECK_RETURN_CRITICAL
+static int ssl_tls13_generate_application_keys(
     mbedtls_ssl_context *ssl,
     mbedtls_ssl_key_set *traffic_keys)
 {
@@ -1612,7 +1675,7 @@
     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
 
     /* Compute handshake secret */
-    ret = mbedtls_ssl_tls13_key_schedule_stage_handshake(ssl);
+    ret = ssl_tls13_key_schedule_stage_handshake(ssl);
     if (ret != 0) {
         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_master_secret", ret);
         goto cleanup;
@@ -1620,9 +1683,9 @@
 
     /* Next evolution in key schedule: Establish handshake secret and
      * key material. */
-    ret = mbedtls_ssl_tls13_generate_handshake_keys(ssl, &traffic_keys);
+    ret = ssl_tls13_generate_handshake_keys(ssl, &traffic_keys);
     if (ret != 0) {
-        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_generate_handshake_keys",
+        MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_generate_handshake_keys",
                               ret);
         goto cleanup;
     }
@@ -1702,17 +1765,17 @@
     mbedtls_ssl_key_set traffic_keys;
     mbedtls_ssl_transform *transform_application = NULL;
 
-    ret = mbedtls_ssl_tls13_key_schedule_stage_application(ssl);
+    ret = ssl_tls13_key_schedule_stage_application(ssl);
     if (ret != 0) {
         MBEDTLS_SSL_DEBUG_RET(1,
-                              "mbedtls_ssl_tls13_key_schedule_stage_application", ret);
+                              "ssl_tls13_key_schedule_stage_application", ret);
         goto cleanup;
     }
 
-    ret = mbedtls_ssl_tls13_generate_application_keys(ssl, &traffic_keys);
+    ret = ssl_tls13_generate_application_keys(ssl, &traffic_keys);
     if (ret != 0) {
         MBEDTLS_SSL_DEBUG_RET(1,
-                              "mbedtls_ssl_tls13_generate_application_keys", ret);
+                              "ssl_tls13_generate_application_keys", ret);
         goto cleanup;
     }
 
diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h
index d4f2b40..21e9b4d 100644
--- a/library/ssl_tls13_keys.h
+++ b/library/ssl_tls13_keys.h
@@ -554,76 +554,6 @@
 int mbedtls_ssl_tls13_key_schedule_stage_early(mbedtls_ssl_context *ssl);
 
 /**
- * \brief Transition into handshake stage of TLS 1.3 key schedule.
- *
- *        The TLS 1.3 key schedule can be viewed as a simple state machine
- *        with states Initial -> Early -> Handshake -> Application, and
- *        this function represents the Early -> Handshake transition.
- *
- *        In the handshake stage, mbedtls_ssl_tls13_generate_handshake_keys()
- *        can be used to derive the handshake traffic keys.
- *
- * \param ssl  The SSL context to operate on. This must be in key schedule
- *             stage \c Early.
- *
- * \returns    \c 0 on success.
- * \returns    A negative error code on failure.
- */
-MBEDTLS_CHECK_RETURN_CRITICAL
-int mbedtls_ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl);
-
-/**
- * \brief Compute TLS 1.3 handshake traffic keys.
- *
- * \param ssl  The SSL context to operate on. This must be in
- *             key schedule stage \c Handshake, see
- *             mbedtls_ssl_tls13_key_schedule_stage_handshake().
- * \param traffic_keys The address at which to store the handshake traffic key
- *                     keys. This must be writable but may be uninitialized.
- *
- * \returns    \c 0 on success.
- * \returns    A negative error code on failure.
- */
-MBEDTLS_CHECK_RETURN_CRITICAL
-int mbedtls_ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl,
-                                              mbedtls_ssl_key_set *traffic_keys);
-
-/**
- * \brief Transition into application stage of TLS 1.3 key schedule.
- *
- *        The TLS 1.3 key schedule can be viewed as a simple state machine
- *        with states Initial -> Early -> Handshake -> Application, and
- *        this function represents the Handshake -> Application transition.
- *
- *        In the handshake stage, mbedtls_ssl_tls13_generate_application_keys()
- *        can be used to derive the handshake traffic keys.
- *
- * \param ssl  The SSL context to operate on. This must be in key schedule
- *             stage \c Handshake.
- *
- * \returns    \c 0 on success.
- * \returns    A negative error code on failure.
- */
-MBEDTLS_CHECK_RETURN_CRITICAL
-int mbedtls_ssl_tls13_key_schedule_stage_application(mbedtls_ssl_context *ssl);
-
-/**
- * \brief Compute TLS 1.3 application traffic keys.
- *
- * \param ssl  The SSL context to operate on. This must be in
- *             key schedule stage \c Application, see
- *             mbedtls_ssl_tls13_key_schedule_stage_application().
- * \param traffic_keys The address at which to store the application traffic key
- *                     keys. This must be writable but may be uninitialized.
- *
- * \returns    \c 0 on success.
- * \returns    A negative error code on failure.
- */
-MBEDTLS_CHECK_RETURN_CRITICAL
-int mbedtls_ssl_tls13_generate_application_keys(
-    mbedtls_ssl_context *ssl, mbedtls_ssl_key_set *traffic_keys);
-
-/**
  * \brief Compute TLS 1.3 resumption master secret.
  *
  * \param ssl  The SSL context to operate on. This must be in
diff --git a/library/x509.c b/library/x509.c
index 1b3701c..81e30e4 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -1107,4 +1107,489 @@
     return 0;
 }
 #endif /* MBEDTLS_HAVE_TIME_DATE */
+
+/* Common functions for parsing CRT and CSR. */
+#if defined(MBEDTLS_X509_CRT_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C)
+/*
+ * OtherName ::= SEQUENCE {
+ *      type-id    OBJECT IDENTIFIER,
+ *      value      [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * HardwareModuleName ::= SEQUENCE {
+ *                           hwType OBJECT IDENTIFIER,
+ *                           hwSerialNum OCTET STRING }
+ *
+ * NOTE: we currently only parse and use otherName of type HwModuleName,
+ * as defined in RFC 4108.
+ */
+static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
+                               mbedtls_x509_san_other_name *other_name)
+{
+    int ret = 0;
+    size_t len;
+    unsigned char *p = subject_alt_name->p;
+    const unsigned char *end = p + subject_alt_name->len;
+    mbedtls_x509_buf cur_oid;
+
+    if ((subject_alt_name->tag &
+         (MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK)) !=
+        (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME)) {
+        /*
+         * The given subject alternative name is not of type "othername".
+         */
+        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
+    }
+
+    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
+                                    MBEDTLS_ASN1_OID)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    cur_oid.tag = MBEDTLS_ASN1_OID;
+    cur_oid.p = p;
+    cur_oid.len = len;
+
+    /*
+     * Only HwModuleName is currently supported.
+     */
+    if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) {
+        return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
+    }
+
+    if (p + len >= end) {
+        mbedtls_platform_zeroize(other_name, sizeof(*other_name));
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+    p += len;
+    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
+                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
+        0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
+                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
+    other_name->value.hardware_module_name.oid.p = p;
+    other_name->value.hardware_module_name.oid.len = len;
+
+    if (p + len >= end) {
+        mbedtls_platform_zeroize(other_name, sizeof(*other_name));
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+    p += len;
+    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
+                                    MBEDTLS_ASN1_OCTET_STRING)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
+    other_name->value.hardware_module_name.val.p = p;
+    other_name->value.hardware_module_name.val.len = len;
+    p += len;
+    if (p != end) {
+        mbedtls_platform_zeroize(other_name,
+                                 sizeof(*other_name));
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+    return 0;
+}
+
+/*
+ * SubjectAltName ::= GeneralNames
+ *
+ * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+ *
+ * GeneralName ::= CHOICE {
+ *      otherName                       [0]     OtherName,
+ *      rfc822Name                      [1]     IA5String,
+ *      dNSName                         [2]     IA5String,
+ *      x400Address                     [3]     ORAddress,
+ *      directoryName                   [4]     Name,
+ *      ediPartyName                    [5]     EDIPartyName,
+ *      uniformResourceIdentifier       [6]     IA5String,
+ *      iPAddress                       [7]     OCTET STRING,
+ *      registeredID                    [8]     OBJECT IDENTIFIER }
+ *
+ * OtherName ::= SEQUENCE {
+ *      type-id    OBJECT IDENTIFIER,
+ *      value      [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * EDIPartyName ::= SEQUENCE {
+ *      nameAssigner            [0]     DirectoryString OPTIONAL,
+ *      partyName               [1]     DirectoryString }
+ *
+ * NOTE: we list all types, but only use dNSName and otherName
+ * of type HwModuleName, as defined in RFC 4108, at this point.
+ */
+int mbedtls_x509_get_subject_alt_name(unsigned char **p,
+                                      const unsigned char *end,
+                                      mbedtls_x509_sequence *subject_alt_name)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t len, tag_len;
+    mbedtls_asn1_buf *buf;
+    unsigned char tag;
+    mbedtls_asn1_sequence *cur = subject_alt_name;
+
+    /* Get main sequence tag */
+    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    if (*p + len != end) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+
+    while (*p < end) {
+        mbedtls_x509_subject_alternative_name dummy_san_buf;
+        memset(&dummy_san_buf, 0, sizeof(dummy_san_buf));
+
+        tag = **p;
+        (*p)++;
+        if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
+            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+        }
+
+        if ((tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
+            MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
+            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                     MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
+        }
+
+        /*
+         * Check that the SAN is structured correctly.
+         */
+        ret = mbedtls_x509_parse_subject_alt_name(&(cur->buf), &dummy_san_buf);
+        /*
+         * In case the extension is malformed, return an error,
+         * and clear the allocated sequences.
+         */
+        if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
+            mbedtls_asn1_sequence_free(subject_alt_name->next);
+            subject_alt_name->next = NULL;
+            return ret;
+        }
+
+        /* Allocate and assign next pointer */
+        if (cur->buf.p != NULL) {
+            if (cur->next != NULL) {
+                return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
+            }
+
+            cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
+
+            if (cur->next == NULL) {
+                return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                         MBEDTLS_ERR_ASN1_ALLOC_FAILED);
+            }
+
+            cur = cur->next;
+        }
+
+        buf = &(cur->buf);
+        buf->tag = tag;
+        buf->p = *p;
+        buf->len = tag_len;
+        *p += buf->len;
+    }
+
+    /* Set final sequence entry's next pointer to NULL */
+    cur->next = NULL;
+
+    if (*p != end) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+
+    return 0;
+}
+
+int mbedtls_x509_get_ns_cert_type(unsigned char **p,
+                                  const unsigned char *end,
+                                  unsigned char *ns_cert_type)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_x509_bitstring bs = { 0, 0, NULL };
+
+    if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    /* A bitstring with no flags set is still technically valid, as it will mean
+       that the certificate has no designated purpose at the time of creation. */
+    if (bs.len == 0) {
+        *ns_cert_type = 0;
+        return 0;
+    }
+
+    if (bs.len != 1) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_INVALID_LENGTH);
+    }
+
+    /* Get actual bitstring */
+    *ns_cert_type = *bs.p;
+    return 0;
+}
+
+int mbedtls_x509_get_key_usage(unsigned char **p,
+                               const unsigned char *end,
+                               unsigned int *key_usage)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t i;
+    mbedtls_x509_bitstring bs = { 0, 0, NULL };
+
+    if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    /* A bitstring with no flags set is still technically valid, as it will mean
+       that the certificate has no designated purpose at the time of creation. */
+    if (bs.len == 0) {
+        *key_usage = 0;
+        return 0;
+    }
+
+    /* Get actual bitstring */
+    *key_usage = 0;
+    for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) {
+        *key_usage |= (unsigned int) bs.p[i] << (8*i);
+    }
+
+    return 0;
+}
+
+int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
+                                        mbedtls_x509_subject_alternative_name *san)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    switch (san_buf->tag &
+            (MBEDTLS_ASN1_TAG_CLASS_MASK |
+             MBEDTLS_ASN1_TAG_VALUE_MASK)) {
+        /*
+         * otherName
+         */
+        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME):
+        {
+            mbedtls_x509_san_other_name other_name;
+
+            ret = x509_get_other_name(san_buf, &other_name);
+            if (ret != 0) {
+                return ret;
+            }
+
+            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
+            san->type = MBEDTLS_X509_SAN_OTHER_NAME;
+            memcpy(&san->san.other_name,
+                   &other_name, sizeof(other_name));
+
+        }
+        break;
+
+        /*
+         * dNSName
+         */
+        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME):
+        {
+            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
+            san->type = MBEDTLS_X509_SAN_DNS_NAME;
+
+            memcpy(&san->san.unstructured_name,
+                   san_buf, sizeof(*san_buf));
+
+        }
+        break;
+
+        /*
+         * Type not supported
+         */
+        default:
+            return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
+    }
+    return 0;
+}
+
+#if !defined(MBEDTLS_X509_REMOVE_INFO)
+int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
+                                       const mbedtls_x509_sequence
+                                       *subject_alt_name,
+                                       const char *prefix)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t i;
+    size_t n = *size;
+    char *p = *buf;
+    const mbedtls_x509_sequence *cur = subject_alt_name;
+    mbedtls_x509_subject_alternative_name san;
+    int parse_ret;
+
+    while (cur != NULL) {
+        memset(&san, 0, sizeof(san));
+        parse_ret = mbedtls_x509_parse_subject_alt_name(&cur->buf, &san);
+        if (parse_ret != 0) {
+            if (parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
+                ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
+                MBEDTLS_X509_SAFE_SNPRINTF;
+            } else {
+                ret = mbedtls_snprintf(p, n, "\n%s    <malformed>", prefix);
+                MBEDTLS_X509_SAFE_SNPRINTF;
+            }
+            cur = cur->next;
+            continue;
+        }
+
+        switch (san.type) {
+            /*
+             * otherName
+             */
+            case MBEDTLS_X509_SAN_OTHER_NAME:
+            {
+                mbedtls_x509_san_other_name *other_name = &san.san.other_name;
+
+                ret = mbedtls_snprintf(p, n, "\n%s    otherName :", prefix);
+                MBEDTLS_X509_SAFE_SNPRINTF;
+
+                if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME,
+                                    &other_name->value.hardware_module_name.oid) != 0) {
+                    ret = mbedtls_snprintf(p, n, "\n%s        hardware module name :", prefix);
+                    MBEDTLS_X509_SAFE_SNPRINTF;
+                    ret =
+                        mbedtls_snprintf(p, n, "\n%s            hardware type          : ", prefix);
+                    MBEDTLS_X509_SAFE_SNPRINTF;
+
+                    ret = mbedtls_oid_get_numeric_string(p,
+                                                         n,
+                                                         &other_name->value.hardware_module_name.oid);
+                    MBEDTLS_X509_SAFE_SNPRINTF;
+
+                    ret =
+                        mbedtls_snprintf(p, n, "\n%s            hardware serial number : ", prefix);
+                    MBEDTLS_X509_SAFE_SNPRINTF;
+
+                    for (i = 0; i < other_name->value.hardware_module_name.val.len; i++) {
+                        ret = mbedtls_snprintf(p,
+                                               n,
+                                               "%02X",
+                                               other_name->value.hardware_module_name.val.p[i]);
+                        MBEDTLS_X509_SAFE_SNPRINTF;
+                    }
+                }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
+            }
+            break;
+
+            /*
+             * dNSName
+             */
+            case MBEDTLS_X509_SAN_DNS_NAME:
+            {
+                ret = mbedtls_snprintf(p, n, "\n%s    dNSName : ", prefix);
+                MBEDTLS_X509_SAFE_SNPRINTF;
+                if (san.san.unstructured_name.len >= n) {
+                    *p = '\0';
+                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
+                }
+
+                memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
+                p += san.san.unstructured_name.len;
+                n -= san.san.unstructured_name.len;
+            }
+            break;
+
+            /*
+             * Type not supported, skip item.
+             */
+            default:
+                ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
+                MBEDTLS_X509_SAFE_SNPRINTF;
+                break;
+        }
+
+        cur = cur->next;
+    }
+
+    *p = '\0';
+
+    *size = n;
+    *buf = p;
+
+    return 0;
+}
+
+#define PRINT_ITEM(i)                           \
+    {                                           \
+        ret = mbedtls_snprintf(p, n, "%s" i, sep);    \
+        MBEDTLS_X509_SAFE_SNPRINTF;                        \
+        sep = ", ";                             \
+    }
+
+#define CERT_TYPE(type, name)                    \
+    if (ns_cert_type & (type))                 \
+    PRINT_ITEM(name);
+
+int mbedtls_x509_info_cert_type(char **buf, size_t *size,
+                                unsigned char ns_cert_type)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t n = *size;
+    char *p = *buf;
+    const char *sep = "";
+
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA");
+
+    *size = n;
+    *buf = p;
+
+    return 0;
+}
+
+#define KEY_USAGE(code, name)    \
+    if (key_usage & (code))    \
+    PRINT_ITEM(name);
+
+int mbedtls_x509_info_key_usage(char **buf, size_t *size,
+                                unsigned int key_usage)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t n = *size;
+    char *p = *buf;
+    const char *sep = "";
+
+    KEY_USAGE(MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature");
+    KEY_USAGE(MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation");
+    KEY_USAGE(MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment");
+    KEY_USAGE(MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment");
+    KEY_USAGE(MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement");
+    KEY_USAGE(MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign");
+    KEY_USAGE(MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign");
+    KEY_USAGE(MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only");
+    KEY_USAGE(MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only");
+
+    *size = n;
+    *buf = p;
+
+    return 0;
+}
+#endif /* MBEDTLS_X509_REMOVE_INFO */
+#endif /* MBEDTLS_X509_CRT_PARSE_C || MBEDTLS_X509_CSR_PARSE_C */
 #endif /* MBEDTLS_X509_USE_C */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 0330097..ecb903f 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -562,53 +562,6 @@
     return 0;
 }
 
-static int x509_get_ns_cert_type(unsigned char **p,
-                                 const unsigned char *end,
-                                 unsigned char *ns_cert_type)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_x509_bitstring bs = { 0, 0, NULL };
-
-    if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    if (bs.len != 1) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_INVALID_LENGTH);
-    }
-
-    /* Get actual bitstring */
-    *ns_cert_type = *bs.p;
-    return 0;
-}
-
-static int x509_get_key_usage(unsigned char **p,
-                              const unsigned char *end,
-                              unsigned int *key_usage)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t i;
-    mbedtls_x509_bitstring bs = { 0, 0, NULL };
-
-    if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    if (bs.len < 1) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_INVALID_LENGTH);
-    }
-
-    /* Get actual bitstring */
-    *key_usage = 0;
-    for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) {
-        *key_usage |= (unsigned int) bs.p[i] << (8*i);
-    }
-
-    return 0;
-}
-
 /*
  * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
  *
@@ -634,118 +587,6 @@
 }
 
 /*
- * SubjectAltName ::= GeneralNames
- *
- * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
- *
- * GeneralName ::= CHOICE {
- *      otherName                       [0]     OtherName,
- *      rfc822Name                      [1]     IA5String,
- *      dNSName                         [2]     IA5String,
- *      x400Address                     [3]     ORAddress,
- *      directoryName                   [4]     Name,
- *      ediPartyName                    [5]     EDIPartyName,
- *      uniformResourceIdentifier       [6]     IA5String,
- *      iPAddress                       [7]     OCTET STRING,
- *      registeredID                    [8]     OBJECT IDENTIFIER }
- *
- * OtherName ::= SEQUENCE {
- *      type-id    OBJECT IDENTIFIER,
- *      value      [0] EXPLICIT ANY DEFINED BY type-id }
- *
- * EDIPartyName ::= SEQUENCE {
- *      nameAssigner            [0]     DirectoryString OPTIONAL,
- *      partyName               [1]     DirectoryString }
- *
- * NOTE: we list all types, but only use dNSName and otherName
- * of type HwModuleName, as defined in RFC 4108, at this point.
- */
-static int x509_get_subject_alt_name(unsigned char **p,
-                                     const unsigned char *end,
-                                     mbedtls_x509_sequence *subject_alt_name)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t len, tag_len;
-    mbedtls_asn1_buf *buf;
-    unsigned char tag;
-    mbedtls_asn1_sequence *cur = subject_alt_name;
-
-    /* Get main sequence tag */
-    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
-                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    if (*p + len != end) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
-    }
-
-    while (*p < end) {
-        mbedtls_x509_subject_alternative_name dummy_san_buf;
-        memset(&dummy_san_buf, 0, sizeof(dummy_san_buf));
-
-        tag = **p;
-        (*p)++;
-        if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
-            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-        }
-
-        if ((tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
-            MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
-            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                     MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
-        }
-
-        /*
-         * Check that the SAN is structured correctly.
-         */
-        ret = mbedtls_x509_parse_subject_alt_name(&(cur->buf), &dummy_san_buf);
-        /*
-         * In case the extension is malformed, return an error,
-         * and clear the allocated sequences.
-         */
-        if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
-            mbedtls_asn1_sequence_free(subject_alt_name->next);
-            subject_alt_name->next = NULL;
-            return ret;
-        }
-
-        /* Allocate and assign next pointer */
-        if (cur->buf.p != NULL) {
-            if (cur->next != NULL) {
-                return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
-            }
-
-            cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
-
-            if (cur->next == NULL) {
-                return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                         MBEDTLS_ERR_ASN1_ALLOC_FAILED);
-            }
-
-            cur = cur->next;
-        }
-
-        buf = &(cur->buf);
-        buf->tag = tag;
-        buf->p = *p;
-        buf->len = tag_len;
-        *p += buf->len;
-    }
-
-    /* Set final sequence entry's next pointer to NULL */
-    cur->next = NULL;
-
-    if (*p != end) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
-    }
-
-    return 0;
-}
-
-/*
  * id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 }
  *
  * anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
@@ -1029,8 +870,8 @@
 
             case MBEDTLS_X509_EXT_KEY_USAGE:
                 /* Parse key usage */
-                if ((ret = x509_get_key_usage(p, end_ext_octet,
-                                              &crt->key_usage)) != 0) {
+                if ((ret = mbedtls_x509_get_key_usage(p, end_ext_octet,
+                                                      &crt->key_usage)) != 0) {
                     return ret;
                 }
                 break;
@@ -1045,16 +886,16 @@
 
             case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
                 /* Parse subject alt name */
-                if ((ret = x509_get_subject_alt_name(p, end_ext_octet,
-                                                     &crt->subject_alt_names)) != 0) {
+                if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_octet,
+                                                             &crt->subject_alt_names)) != 0) {
                     return ret;
                 }
                 break;
 
             case MBEDTLS_X509_EXT_NS_CERT_TYPE:
                 /* Parse netscape certificate type */
-                if ((ret = x509_get_ns_cert_type(p, end_ext_octet,
-                                                 &crt->ns_cert_type)) != 0) {
+                if ((ret = mbedtls_x509_get_ns_cert_type(p, end_ext_octet,
+                                                         &crt->ns_cert_type)) != 0) {
                     return ret;
                 }
                 break;
@@ -1652,10 +1493,10 @@
     memset(&sb, 0, sizeof(sb));
 
     while ((entry = readdir(dir)) != NULL) {
-        snp_ret = mbedtls_snprintf(entry_name, sizeof entry_name,
+        snp_ret = mbedtls_snprintf(entry_name, sizeof(entry_name),
                                    "%s/%s", path, entry->d_name);
 
-        if (snp_ret < 0 || (size_t) snp_ret >= sizeof entry_name) {
+        if (snp_ret < 0 || (size_t) snp_ret >= sizeof(entry_name)) {
             ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
             goto cleanup;
         } else if (stat(entry_name, &sb) == -1) {
@@ -1703,319 +1544,7 @@
 }
 #endif /* MBEDTLS_FS_IO */
 
-/*
- * OtherName ::= SEQUENCE {
- *      type-id    OBJECT IDENTIFIER,
- *      value      [0] EXPLICIT ANY DEFINED BY type-id }
- *
- * HardwareModuleName ::= SEQUENCE {
- *                           hwType OBJECT IDENTIFIER,
- *                           hwSerialNum OCTET STRING }
- *
- * NOTE: we currently only parse and use otherName of type HwModuleName,
- * as defined in RFC 4108.
- */
-static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
-                               mbedtls_x509_san_other_name *other_name)
-{
-    int ret = 0;
-    size_t len;
-    unsigned char *p = subject_alt_name->p;
-    const unsigned char *end = p + subject_alt_name->len;
-    mbedtls_x509_buf cur_oid;
-
-    if ((subject_alt_name->tag &
-         (MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK)) !=
-        (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME)) {
-        /*
-         * The given subject alternative name is not of type "othername".
-         */
-        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
-    }
-
-    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
-                                    MBEDTLS_ASN1_OID)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    cur_oid.tag = MBEDTLS_ASN1_OID;
-    cur_oid.p = p;
-    cur_oid.len = len;
-
-    /*
-     * Only HwModuleName is currently supported.
-     */
-    if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) {
-        return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
-    }
-
-    if (p + len >= end) {
-        mbedtls_platform_zeroize(other_name, sizeof(*other_name));
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
-    }
-    p += len;
-    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
-                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
-        0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
-                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
-    other_name->value.hardware_module_name.oid.p = p;
-    other_name->value.hardware_module_name.oid.len = len;
-
-    if (p + len >= end) {
-        mbedtls_platform_zeroize(other_name, sizeof(*other_name));
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
-    }
-    p += len;
-    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
-                                    MBEDTLS_ASN1_OCTET_STRING)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
-    other_name->value.hardware_module_name.val.p = p;
-    other_name->value.hardware_module_name.val.len = len;
-    p += len;
-    if (p != end) {
-        mbedtls_platform_zeroize(other_name,
-                                 sizeof(*other_name));
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
-    }
-    return 0;
-}
-
-int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
-                                        mbedtls_x509_subject_alternative_name *san)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    switch (san_buf->tag &
-            (MBEDTLS_ASN1_TAG_CLASS_MASK |
-             MBEDTLS_ASN1_TAG_VALUE_MASK)) {
-        /*
-         * otherName
-         */
-        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME):
-        {
-            mbedtls_x509_san_other_name other_name;
-
-            ret = x509_get_other_name(san_buf, &other_name);
-            if (ret != 0) {
-                return ret;
-            }
-
-            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
-            san->type = MBEDTLS_X509_SAN_OTHER_NAME;
-            memcpy(&san->san.other_name,
-                   &other_name, sizeof(other_name));
-
-        }
-        break;
-
-        /*
-         * dNSName
-         */
-        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME):
-        {
-            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
-            san->type = MBEDTLS_X509_SAN_DNS_NAME;
-
-            memcpy(&san->san.unstructured_name,
-                   san_buf, sizeof(*san_buf));
-
-        }
-        break;
-
-        /*
-         * Type not supported
-         */
-        default:
-            return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
-    }
-    return 0;
-}
-
 #if !defined(MBEDTLS_X509_REMOVE_INFO)
-static int x509_info_subject_alt_name(char **buf, size_t *size,
-                                      const mbedtls_x509_sequence
-                                      *subject_alt_name,
-                                      const char *prefix)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t i;
-    size_t n = *size;
-    char *p = *buf;
-    const mbedtls_x509_sequence *cur = subject_alt_name;
-    mbedtls_x509_subject_alternative_name san;
-    int parse_ret;
-
-    while (cur != NULL) {
-        memset(&san, 0, sizeof(san));
-        parse_ret = mbedtls_x509_parse_subject_alt_name(&cur->buf, &san);
-        if (parse_ret != 0) {
-            if (parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
-                ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
-                MBEDTLS_X509_SAFE_SNPRINTF;
-            } else {
-                ret = mbedtls_snprintf(p, n, "\n%s    <malformed>", prefix);
-                MBEDTLS_X509_SAFE_SNPRINTF;
-            }
-            cur = cur->next;
-            continue;
-        }
-
-        switch (san.type) {
-            /*
-             * otherName
-             */
-            case MBEDTLS_X509_SAN_OTHER_NAME:
-            {
-                mbedtls_x509_san_other_name *other_name = &san.san.other_name;
-
-                ret = mbedtls_snprintf(p, n, "\n%s    otherName :", prefix);
-                MBEDTLS_X509_SAFE_SNPRINTF;
-
-                if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME,
-                                    &other_name->value.hardware_module_name.oid) != 0) {
-                    ret = mbedtls_snprintf(p, n, "\n%s        hardware module name :", prefix);
-                    MBEDTLS_X509_SAFE_SNPRINTF;
-                    ret =
-                        mbedtls_snprintf(p, n, "\n%s            hardware type          : ", prefix);
-                    MBEDTLS_X509_SAFE_SNPRINTF;
-
-                    ret = mbedtls_oid_get_numeric_string(p,
-                                                         n,
-                                                         &other_name->value.hardware_module_name.oid);
-                    MBEDTLS_X509_SAFE_SNPRINTF;
-
-                    ret =
-                        mbedtls_snprintf(p, n, "\n%s            hardware serial number : ", prefix);
-                    MBEDTLS_X509_SAFE_SNPRINTF;
-
-                    for (i = 0; i < other_name->value.hardware_module_name.val.len; i++) {
-                        ret = mbedtls_snprintf(p,
-                                               n,
-                                               "%02X",
-                                               other_name->value.hardware_module_name.val.p[i]);
-                        MBEDTLS_X509_SAFE_SNPRINTF;
-                    }
-                }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
-            }
-            break;
-
-            /*
-             * dNSName
-             */
-            case MBEDTLS_X509_SAN_DNS_NAME:
-            {
-                ret = mbedtls_snprintf(p, n, "\n%s    dNSName : ", prefix);
-                MBEDTLS_X509_SAFE_SNPRINTF;
-                if (san.san.unstructured_name.len >= n) {
-                    *p = '\0';
-                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
-                }
-
-                memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
-                p += san.san.unstructured_name.len;
-                n -= san.san.unstructured_name.len;
-            }
-            break;
-
-            /*
-             * Type not supported, skip item.
-             */
-            default:
-                ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
-                MBEDTLS_X509_SAFE_SNPRINTF;
-                break;
-        }
-
-        cur = cur->next;
-    }
-
-    *p = '\0';
-
-    *size = n;
-    *buf = p;
-
-    return 0;
-}
-
-#define PRINT_ITEM(i)                           \
-    {                                           \
-        ret = mbedtls_snprintf(p, n, "%s" i, sep);    \
-        MBEDTLS_X509_SAFE_SNPRINTF;                        \
-        sep = ", ";                             \
-    }
-
-#define CERT_TYPE(type, name)                    \
-    if (ns_cert_type & (type))                 \
-    PRINT_ITEM(name);
-
-static int x509_info_cert_type(char **buf, size_t *size,
-                               unsigned char ns_cert_type)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t n = *size;
-    char *p = *buf;
-    const char *sep = "";
-
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA");
-
-    *size = n;
-    *buf = p;
-
-    return 0;
-}
-
-#define KEY_USAGE(code, name)    \
-    if (key_usage & (code))    \
-    PRINT_ITEM(name);
-
-static int x509_info_key_usage(char **buf, size_t *size,
-                               unsigned int key_usage)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t n = *size;
-    char *p = *buf;
-    const char *sep = "";
-
-    KEY_USAGE(MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature");
-    KEY_USAGE(MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation");
-    KEY_USAGE(MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment");
-    KEY_USAGE(MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment");
-    KEY_USAGE(MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement");
-    KEY_USAGE(MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign");
-    KEY_USAGE(MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign");
-    KEY_USAGE(MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only");
-    KEY_USAGE(MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only");
-
-    *size = n;
-    *buf = p;
-
-    return 0;
-}
-
 static int x509_info_ext_key_usage(char **buf, size_t *size,
                                    const mbedtls_x509_sequence *extended_key_usage)
 {
@@ -2167,9 +1696,9 @@
         ret = mbedtls_snprintf(p, n, "\n%ssubject alt name  :", prefix);
         MBEDTLS_X509_SAFE_SNPRINTF;
 
-        if ((ret = x509_info_subject_alt_name(&p, &n,
-                                              &crt->subject_alt_names,
-                                              prefix)) != 0) {
+        if ((ret = mbedtls_x509_info_subject_alt_name(&p, &n,
+                                                      &crt->subject_alt_names,
+                                                      prefix)) != 0) {
             return ret;
         }
     }
@@ -2178,7 +1707,7 @@
         ret = mbedtls_snprintf(p, n, "\n%scert. type        : ", prefix);
         MBEDTLS_X509_SAFE_SNPRINTF;
 
-        if ((ret = x509_info_cert_type(&p, &n, crt->ns_cert_type)) != 0) {
+        if ((ret = mbedtls_x509_info_cert_type(&p, &n, crt->ns_cert_type)) != 0) {
             return ret;
         }
     }
@@ -2187,7 +1716,7 @@
         ret = mbedtls_snprintf(p, n, "\n%skey usage         : ", prefix);
         MBEDTLS_X509_SAFE_SNPRINTF;
 
-        if ((ret = x509_info_key_usage(&p, &n, crt->key_usage)) != 0) {
+        if ((ret = mbedtls_x509_info_key_usage(&p, &n, crt->key_usage)) != 0) {
             return ret;
         }
     }
diff --git a/library/x509_csr.c b/library/x509_csr.c
index 0c664d9..cd117cb 100644
--- a/library/x509_csr.c
+++ b/library/x509_csr.c
@@ -70,6 +70,165 @@
 }
 
 /*
+ * Parse CSR extension requests in DER format
+ */
+static int x509_csr_parse_extensions(mbedtls_x509_csr *csr,
+                                     unsigned char **p, const unsigned char *end)
+{
+    int ret;
+    size_t len;
+    unsigned char *end_ext_data;
+    while (*p < end) {
+        mbedtls_x509_buf extn_oid = { 0, 0, NULL };
+        int ext_type = 0;
+
+        /* Read sequence tag */
+        if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+                                        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+        }
+
+        end_ext_data = *p + len;
+
+        /* Get extension ID */
+        if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &extn_oid.len,
+                                        MBEDTLS_ASN1_OID)) != 0) {
+            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+        }
+
+        extn_oid.tag = MBEDTLS_ASN1_OID;
+        extn_oid.p = *p;
+        *p += extn_oid.len;
+
+        /* Data should be octet string type */
+        if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
+                                        MBEDTLS_ASN1_OCTET_STRING)) != 0) {
+            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+        }
+
+        if (*p + len != end_ext_data) {
+            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+        }
+
+        /*
+         * Detect supported extensions and skip unsupported extensions
+         */
+        ret = mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type);
+
+        if (ret == 0) {
+            /* Forbid repeated extensions */
+            if ((csr->ext_types & ext_type) != 0) {
+                return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                         MBEDTLS_ERR_ASN1_INVALID_DATA);
+            }
+
+            csr->ext_types |= ext_type;
+
+            switch (ext_type) {
+                case MBEDTLS_X509_EXT_KEY_USAGE:
+                    /* Parse key usage */
+                    if ((ret = mbedtls_x509_get_key_usage(p, end_ext_data,
+                                                          &csr->key_usage)) != 0) {
+                        return ret;
+                    }
+                    break;
+
+                case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
+                    /* Parse subject alt name */
+                    if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_data,
+                                                                 &csr->subject_alt_names)) != 0) {
+                        return ret;
+                    }
+                    break;
+
+                case MBEDTLS_X509_EXT_NS_CERT_TYPE:
+                    /* Parse netscape certificate type */
+                    if ((ret = mbedtls_x509_get_ns_cert_type(p, end_ext_data,
+                                                             &csr->ns_cert_type)) != 0) {
+                        return ret;
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+        *p = end_ext_data;
+    }
+
+    if (*p != end) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+
+    return 0;
+}
+
+/*
+ * Parse CSR attributes in DER format
+ */
+static int x509_csr_parse_attributes(mbedtls_x509_csr *csr,
+                                     const unsigned char *start, const unsigned char *end)
+{
+    int ret;
+    size_t len;
+    unsigned char *end_attr_data;
+    unsigned char **p = (unsigned char **) &start;
+
+    while (*p < end) {
+        mbedtls_x509_buf attr_oid = { 0, 0, NULL };
+
+        if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+                                        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+        }
+        end_attr_data = *p + len;
+
+        /* Get attribute ID */
+        if ((ret = mbedtls_asn1_get_tag(p, end_attr_data, &attr_oid.len,
+                                        MBEDTLS_ASN1_OID)) != 0) {
+            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+        }
+
+        attr_oid.tag = MBEDTLS_ASN1_OID;
+        attr_oid.p = *p;
+        *p += attr_oid.len;
+
+        /* Check that this is an extension-request attribute */
+        if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS9_CSR_EXT_REQ, &attr_oid) == 0) {
+            if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+                                            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) {
+                return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+            }
+
+            if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+                                            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) !=
+                0) {
+                return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+            }
+
+            if ((ret = x509_csr_parse_extensions(csr, p, *p + len)) != 0) {
+                return ret;
+            }
+
+            if (*p != end_attr_data) {
+                return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                         MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+            }
+        }
+
+        *p = end_attr_data;
+    }
+
+    if (*p != end) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+
+    return 0;
+}
+
+/*
  * Parse a CSR in DER format
  */
 int mbedtls_x509_csr_parse_der(mbedtls_x509_csr *csr,
@@ -197,6 +356,11 @@
         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
     }
 
+    if ((ret = x509_csr_parse_attributes(csr, p, p + len)) != 0) {
+        mbedtls_x509_csr_free(csr);
+        return ret;
+    }
+
     p += len;
 
     end = csr->raw.p + csr->raw.len;
@@ -345,6 +509,44 @@
                            (int) mbedtls_pk_get_bitlen(&csr->pk));
     MBEDTLS_X509_SAFE_SNPRINTF;
 
+    /*
+     * Optional extensions
+     */
+
+    if (csr->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
+        ret = mbedtls_snprintf(p, n, "\n%ssubject alt name  :", prefix);
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        if ((ret = mbedtls_x509_info_subject_alt_name(&p, &n,
+                                                      &csr->subject_alt_names,
+                                                      prefix)) != 0) {
+            return ret;
+        }
+    }
+
+    if (csr->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) {
+        ret = mbedtls_snprintf(p, n, "\n%scert. type        : ", prefix);
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        if ((ret = mbedtls_x509_info_cert_type(&p, &n, csr->ns_cert_type)) != 0) {
+            return ret;
+        }
+    }
+
+    if (csr->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) {
+        ret = mbedtls_snprintf(p, n, "\n%skey usage         : ", prefix);
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        if ((ret = mbedtls_x509_info_key_usage(&p, &n, csr->key_usage)) != 0) {
+            return ret;
+        }
+    }
+
+    if (csr->ext_types != 0) {
+        ret = mbedtls_snprintf(p, n, "\n");
+        MBEDTLS_X509_SAFE_SNPRINTF;
+    }
+
     return (int) (size - n);
 }
 #endif /* MBEDTLS_X509_REMOVE_INFO */
@@ -373,6 +575,7 @@
 #endif
 
     mbedtls_asn1_free_named_data_list_shallow(csr->subject.next);
+    mbedtls_asn1_sequence_free(csr->subject_alt_names.next);
 
     if (csr->raw.p != NULL) {
         mbedtls_platform_zeroize(csr->raw.p, csr->raw.len);
diff --git a/programs/pkey/ecdh_curve25519.c b/programs/pkey/ecdh_curve25519.c
index d880a1a..9804417 100644
--- a/programs/pkey/ecdh_curve25519.c
+++ b/programs/pkey/ecdh_curve25519.c
@@ -74,7 +74,7 @@
     if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
                                      &entropy,
                                      (const unsigned char *) pers,
-                                     sizeof pers)) != 0) {
+                                     sizeof(pers))) != 0) {
         mbedtls_printf(" failed\n  ! mbedtls_ctr_drbg_seed returned %d\n",
                        ret);
         goto exit;
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index be2ca90..953c144 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -73,7 +73,7 @@
     size_t len;
 
     if (mbedtls_ecp_point_write_binary(&key->MBEDTLS_PRIVATE(grp), &key->MBEDTLS_PRIVATE(Q),
-                                       MBEDTLS_ECP_PF_UNCOMPRESSED, &len, buf, sizeof buf) != 0) {
+                                       MBEDTLS_ECP_PF_UNCOMPRESSED, &len, buf, sizeof(buf)) != 0) {
         mbedtls_printf("internal error\n");
         return;
     }
diff --git a/tests/compat.sh b/tests/compat.sh
index 7693400..ef82736 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -89,7 +89,7 @@
 # - NULL: excluded from our default config + requires OpenSSL legacy
 # - ARIA: requires OpenSSL >= 1.1.1
 # - ChachaPoly: requires OpenSSL >= 1.1.0
-EXCLUDE='NULL\|ARIA\|CHACHA20-POLY1305'
+EXCLUDE='NULL\|ARIA\|CHACHA20_POLY1305'
 VERBOSE=""
 MEMCHECK=0
 PEERS="OpenSSL$PEER_GNUTLS mbedTLS"
@@ -205,7 +205,7 @@
 check_openssl_server_bug()
 {
     if test "X$VERIFY" = "XYES" && is_dtls "$MODE" && \
-        echo "$1" | grep "^TLS-PSK" >/dev/null;
+        test "$TYPE" = "PSK";
     then
         SKIP_NEXT="YES"
     fi
@@ -239,9 +239,14 @@
     G_CIPHERS=""
 }
 
-check_translation()
+# translate_ciphers {g|m|o} {STANDARD_CIPHER_SUITE_NAME...}
+# Set $ciphers to the cipher suite name translations for the specified
+# program (gnutls, mbedtls or openssl). $ciphers is a space-separated
+# list of entries of the form "STANDARD_NAME=PROGRAM_NAME".
+translate_ciphers()
 {
-    if [ $1 -ne 0 ]; then
+    ciphers=$(scripts/translate_ciphers.py "$@")
+    if [ $? -ne 0 ]; then
         echo "translate_ciphers.py failed with exit code $1" >&2
         echo "$2" >&2
         exit 1
@@ -258,71 +263,66 @@
 
         "ECDSA")
             CIPHERS="$CIPHERS                           \
-                TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA    \
-                TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 \
-                TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
-                TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA    \
-                TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384 \
-                TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 \
-                TLS-ECDHE-ECDSA-WITH-NULL-SHA           \
+                TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA    \
+                TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 \
+                TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 \
+                TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA    \
+                TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 \
+                TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 \
+                TLS_ECDHE_ECDSA_WITH_NULL_SHA           \
                 "
             ;;
 
         "RSA")
             CIPHERS="$CIPHERS                           \
-                TLS-DHE-RSA-WITH-AES-128-CBC-SHA        \
-                TLS-DHE-RSA-WITH-AES-128-CBC-SHA256     \
-                TLS-DHE-RSA-WITH-AES-128-GCM-SHA256     \
-                TLS-DHE-RSA-WITH-AES-256-CBC-SHA        \
-                TLS-DHE-RSA-WITH-AES-256-CBC-SHA256     \
-                TLS-DHE-RSA-WITH-AES-256-GCM-SHA384     \
-                TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA   \
-                TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA   \
-                TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA      \
-                TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256   \
-                TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256   \
-                TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA      \
-                TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384   \
-                TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384   \
-                TLS-ECDHE-RSA-WITH-NULL-SHA             \
-                TLS-RSA-WITH-AES-128-CBC-SHA            \
-                TLS-RSA-WITH-AES-128-CBC-SHA256         \
-                TLS-RSA-WITH-AES-128-GCM-SHA256         \
-                TLS-RSA-WITH-AES-256-CBC-SHA            \
-                TLS-RSA-WITH-AES-256-CBC-SHA256         \
-                TLS-RSA-WITH-AES-256-GCM-SHA384         \
-                TLS-RSA-WITH-CAMELLIA-128-CBC-SHA       \
-                TLS-RSA-WITH-CAMELLIA-256-CBC-SHA       \
-                TLS-RSA-WITH-NULL-MD5                   \
-                TLS-RSA-WITH-NULL-SHA                   \
-                TLS-RSA-WITH-NULL-SHA256                \
+                TLS_DHE_RSA_WITH_AES_128_CBC_SHA        \
+                TLS_DHE_RSA_WITH_AES_128_CBC_SHA256     \
+                TLS_DHE_RSA_WITH_AES_128_GCM_SHA256     \
+                TLS_DHE_RSA_WITH_AES_256_CBC_SHA        \
+                TLS_DHE_RSA_WITH_AES_256_CBC_SHA256     \
+                TLS_DHE_RSA_WITH_AES_256_GCM_SHA384     \
+                TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA   \
+                TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA   \
+                TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA      \
+                TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256   \
+                TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   \
+                TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA      \
+                TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384   \
+                TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384   \
+                TLS_ECDHE_RSA_WITH_NULL_SHA             \
+                TLS_RSA_WITH_AES_128_CBC_SHA            \
+                TLS_RSA_WITH_AES_128_CBC_SHA256         \
+                TLS_RSA_WITH_AES_128_GCM_SHA256         \
+                TLS_RSA_WITH_AES_256_CBC_SHA            \
+                TLS_RSA_WITH_AES_256_CBC_SHA256         \
+                TLS_RSA_WITH_AES_256_GCM_SHA384         \
+                TLS_RSA_WITH_CAMELLIA_128_CBC_SHA       \
+                TLS_RSA_WITH_CAMELLIA_256_CBC_SHA       \
+                TLS_RSA_WITH_NULL_MD5                   \
+                TLS_RSA_WITH_NULL_SHA                   \
+                TLS_RSA_WITH_NULL_SHA256                \
                 "
             ;;
 
         "PSK")
             CIPHERS="$CIPHERS                           \
-                TLS-PSK-WITH-AES-128-CBC-SHA            \
-                TLS-PSK-WITH-AES-256-CBC-SHA            \
+                TLS_PSK_WITH_AES_128_CBC_SHA            \
+                TLS_PSK_WITH_AES_256_CBC_SHA            \
                 "
             ;;
     esac
 
+    O_CIPHERS="$O_CIPHERS $CIPHERS"
+    G_CIPHERS="$G_CIPHERS $CIPHERS"
     M_CIPHERS="$M_CIPHERS $CIPHERS"
-
-    T=$(./scripts/translate_ciphers.py g $CIPHERS)
-    check_translation $? "$T"
-    G_CIPHERS="$G_CIPHERS $T"
-
-    T=$(./scripts/translate_ciphers.py o $CIPHERS)
-    check_translation $? "$T"
-    O_CIPHERS="$O_CIPHERS $T"
 }
 
 # Ciphersuites usable only with Mbed TLS and OpenSSL
-# A list of ciphersuites in the Mbed TLS convention is compiled and
-# appended to the list of Mbed TLS ciphersuites $M_CIPHERS. The same list
-# is translated to the OpenSSL naming convention and appended to the list of
-# OpenSSL ciphersuites $O_CIPHERS.
+# A list of ciphersuites in the standard naming convention is appended
+# to the list of Mbed TLS ciphersuites $M_CIPHERS and
+# to the list of OpenSSL ciphersuites $O_CIPHERS respectively.
+# Based on client's naming convention, all ciphersuite names will be
+# translated into another naming format before sent to the client.
 #
 # NOTE: for some reason RSA-PSK doesn't work with OpenSSL,
 # so RSA-PSK ciphersuites need to go in other sections, see
@@ -337,57 +337,55 @@
 
         "ECDSA")
             CIPHERS="$CIPHERS                                   \
-                TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA             \
-                TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256          \
-                TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256          \
-                TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA             \
-                TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384          \
-                TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384          \
-                TLS-ECDH-ECDSA-WITH-NULL-SHA                    \
-                TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256        \
-                TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384        \
-                TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256   \
+                TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA             \
+                TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256          \
+                TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256          \
+                TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA             \
+                TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384          \
+                TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384          \
+                TLS_ECDH_ECDSA_WITH_NULL_SHA                    \
+                TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256        \
+                TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384        \
+                TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256   \
                 "
             ;;
 
         "RSA")
             CIPHERS="$CIPHERS                                   \
-                TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256            \
-                TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384            \
-                TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256       \
-                TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256          \
-                TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384          \
-                TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256     \
-                TLS-RSA-WITH-ARIA-128-GCM-SHA256                \
-                TLS-RSA-WITH-ARIA-256-GCM-SHA384                \
+                TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256            \
+                TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384            \
+                TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256       \
+                TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256          \
+                TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384          \
+                TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256     \
+                TLS_RSA_WITH_ARIA_128_GCM_SHA256                \
+                TLS_RSA_WITH_ARIA_256_GCM_SHA384                \
                 "
             ;;
 
         "PSK")
             CIPHERS="$CIPHERS                                   \
-                TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256            \
-                TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384            \
-                TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256       \
-                TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256     \
-                TLS-PSK-WITH-ARIA-128-GCM-SHA256                \
-                TLS-PSK-WITH-ARIA-256-GCM-SHA384                \
-                TLS-PSK-WITH-CHACHA20-POLY1305-SHA256           \
+                TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256            \
+                TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384            \
+                TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256       \
+                TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256     \
+                TLS_PSK_WITH_ARIA_128_GCM_SHA256                \
+                TLS_PSK_WITH_ARIA_256_GCM_SHA384                \
+                TLS_PSK_WITH_CHACHA20_POLY1305_SHA256           \
                 "
             ;;
     esac
 
+    O_CIPHERS="$O_CIPHERS $CIPHERS"
     M_CIPHERS="$M_CIPHERS $CIPHERS"
-
-    T=$(./scripts/translate_ciphers.py o $CIPHERS)
-    check_translation $? "$T"
-    O_CIPHERS="$O_CIPHERS $T"
 }
 
 # Ciphersuites usable only with Mbed TLS and GnuTLS
-# A list of ciphersuites in the Mbed TLS convention is compiled and
-# appended to the list of Mbed TLS ciphersuites $M_CIPHERS. The same list
-# is translated to the GnuTLS naming convention and appended to the list of
-# GnuTLS ciphersuites $G_CIPHERS.
+# A list of ciphersuites in the standard naming convention is appended
+# to the list of Mbed TLS ciphersuites $M_CIPHERS and
+# to the list of GnuTLS ciphersuites $G_CIPHERS respectively.
+# Based on client's naming convention, all ciphersuite names will be
+# translated into another naming format before sent to the client.
 add_gnutls_ciphersuites()
 {
     CIPHERS=""
@@ -395,107 +393,104 @@
 
         "ECDSA")
             CIPHERS="$CIPHERS                                       \
-                TLS-ECDHE-ECDSA-WITH-AES-128-CCM                    \
-                TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8                  \
-                TLS-ECDHE-ECDSA-WITH-AES-256-CCM                    \
-                TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8                  \
-                TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256        \
-                TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256        \
-                TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384        \
-                TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384        \
+                TLS_ECDHE_ECDSA_WITH_AES_128_CCM                    \
+                TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8                  \
+                TLS_ECDHE_ECDSA_WITH_AES_256_CCM                    \
+                TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8                  \
+                TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256        \
+                TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256        \
+                TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384        \
+                TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384        \
                 "
             ;;
 
         "RSA")
             CIPHERS="$CIPHERS                               \
-                TLS-DHE-RSA-WITH-AES-128-CCM                \
-                TLS-DHE-RSA-WITH-AES-128-CCM-8              \
-                TLS-DHE-RSA-WITH-AES-256-CCM                \
-                TLS-DHE-RSA-WITH-AES-256-CCM-8              \
-                TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256    \
-                TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256    \
-                TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256    \
-                TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384    \
-                TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256  \
-                TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256  \
-                TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384  \
-                TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384  \
-                TLS-RSA-WITH-AES-128-CCM                    \
-                TLS-RSA-WITH-AES-128-CCM-8                  \
-                TLS-RSA-WITH-AES-256-CCM                    \
-                TLS-RSA-WITH-AES-256-CCM-8                  \
-                TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256        \
-                TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256        \
-                TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256        \
-                TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384        \
+                TLS_DHE_RSA_WITH_AES_128_CCM                \
+                TLS_DHE_RSA_WITH_AES_128_CCM_8              \
+                TLS_DHE_RSA_WITH_AES_256_CCM                \
+                TLS_DHE_RSA_WITH_AES_256_CCM_8              \
+                TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256    \
+                TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256    \
+                TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256    \
+                TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384    \
+                TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256  \
+                TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256  \
+                TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384  \
+                TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384  \
+                TLS_RSA_WITH_AES_128_CCM                    \
+                TLS_RSA_WITH_AES_128_CCM_8                  \
+                TLS_RSA_WITH_AES_256_CCM                    \
+                TLS_RSA_WITH_AES_256_CCM_8                  \
+                TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256        \
+                TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256        \
+                TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256        \
+                TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384        \
                 "
             ;;
 
         "PSK")
             CIPHERS="$CIPHERS                               \
-                TLS-DHE-PSK-WITH-AES-128-CBC-SHA            \
-                TLS-DHE-PSK-WITH-AES-128-CBC-SHA256         \
-                TLS-DHE-PSK-WITH-AES-128-CCM                \
-                TLS-DHE-PSK-WITH-AES-128-CCM-8              \
-                TLS-DHE-PSK-WITH-AES-128-GCM-SHA256         \
-                TLS-DHE-PSK-WITH-AES-256-CBC-SHA            \
-                TLS-DHE-PSK-WITH-AES-256-CBC-SHA384         \
-                TLS-DHE-PSK-WITH-AES-256-CCM                \
-                TLS-DHE-PSK-WITH-AES-256-CCM-8              \
-                TLS-DHE-PSK-WITH-AES-256-GCM-SHA384         \
-                TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256    \
-                TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256    \
-                TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384    \
-                TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384    \
-                TLS-DHE-PSK-WITH-NULL-SHA256                \
-                TLS-DHE-PSK-WITH-NULL-SHA384                \
-                TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA          \
-                TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256       \
-                TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA          \
-                TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384       \
-                TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256  \
-                TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384  \
-                TLS-ECDHE-PSK-WITH-NULL-SHA256              \
-                TLS-ECDHE-PSK-WITH-NULL-SHA384              \
-                TLS-PSK-WITH-AES-128-CBC-SHA256             \
-                TLS-PSK-WITH-AES-128-CCM                    \
-                TLS-PSK-WITH-AES-128-CCM-8                  \
-                TLS-PSK-WITH-AES-128-GCM-SHA256             \
-                TLS-PSK-WITH-AES-256-CBC-SHA384             \
-                TLS-PSK-WITH-AES-256-CCM                    \
-                TLS-PSK-WITH-AES-256-CCM-8                  \
-                TLS-PSK-WITH-AES-256-GCM-SHA384             \
-                TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256        \
-                TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256        \
-                TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384        \
-                TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384        \
-                TLS-PSK-WITH-NULL-SHA256                    \
-                TLS-PSK-WITH-NULL-SHA384                    \
-                TLS-RSA-PSK-WITH-AES-128-CBC-SHA            \
-                TLS-RSA-PSK-WITH-AES-128-CBC-SHA256         \
-                TLS-RSA-PSK-WITH-AES-128-GCM-SHA256         \
-                TLS-RSA-PSK-WITH-AES-256-CBC-SHA            \
-                TLS-RSA-PSK-WITH-AES-256-CBC-SHA384         \
-                TLS-RSA-PSK-WITH-AES-256-GCM-SHA384         \
-                TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256    \
-                TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256    \
-                TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384    \
-                TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384    \
-                TLS-RSA-PSK-WITH-NULL-SHA256                \
-                TLS-RSA-PSK-WITH-NULL-SHA384                \
+                TLS_DHE_PSK_WITH_AES_128_CBC_SHA            \
+                TLS_DHE_PSK_WITH_AES_128_CBC_SHA256         \
+                TLS_DHE_PSK_WITH_AES_128_CCM                \
+                TLS_DHE_PSK_WITH_AES_128_CCM_8              \
+                TLS_DHE_PSK_WITH_AES_128_GCM_SHA256         \
+                TLS_DHE_PSK_WITH_AES_256_CBC_SHA            \
+                TLS_DHE_PSK_WITH_AES_256_CBC_SHA384         \
+                TLS_DHE_PSK_WITH_AES_256_CCM                \
+                TLS_DHE_PSK_WITH_AES_256_CCM_8              \
+                TLS_DHE_PSK_WITH_AES_256_GCM_SHA384         \
+                TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256    \
+                TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256    \
+                TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384    \
+                TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384    \
+                TLS_DHE_PSK_WITH_NULL_SHA256                \
+                TLS_DHE_PSK_WITH_NULL_SHA384                \
+                TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA          \
+                TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256       \
+                TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA          \
+                TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384       \
+                TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256  \
+                TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384  \
+                TLS_ECDHE_PSK_WITH_NULL_SHA256              \
+                TLS_ECDHE_PSK_WITH_NULL_SHA384              \
+                TLS_PSK_WITH_AES_128_CBC_SHA256             \
+                TLS_PSK_WITH_AES_128_CCM                    \
+                TLS_PSK_WITH_AES_128_CCM_8                  \
+                TLS_PSK_WITH_AES_128_GCM_SHA256             \
+                TLS_PSK_WITH_AES_256_CBC_SHA384             \
+                TLS_PSK_WITH_AES_256_CCM                    \
+                TLS_PSK_WITH_AES_256_CCM_8                  \
+                TLS_PSK_WITH_AES_256_GCM_SHA384             \
+                TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256        \
+                TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256        \
+                TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384        \
+                TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384        \
+                TLS_PSK_WITH_NULL_SHA256                    \
+                TLS_PSK_WITH_NULL_SHA384                    \
+                TLS_RSA_PSK_WITH_AES_128_CBC_SHA            \
+                TLS_RSA_PSK_WITH_AES_128_CBC_SHA256         \
+                TLS_RSA_PSK_WITH_AES_128_GCM_SHA256         \
+                TLS_RSA_PSK_WITH_AES_256_CBC_SHA            \
+                TLS_RSA_PSK_WITH_AES_256_CBC_SHA384         \
+                TLS_RSA_PSK_WITH_AES_256_GCM_SHA384         \
+                TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256    \
+                TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256    \
+                TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384    \
+                TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384    \
+                TLS_RSA_PSK_WITH_NULL_SHA256                \
+                TLS_RSA_PSK_WITH_NULL_SHA384                \
                 "
             ;;
     esac
 
+    G_CIPHERS="$G_CIPHERS $CIPHERS"
     M_CIPHERS="$M_CIPHERS $CIPHERS"
-
-    T=$(./scripts/translate_ciphers.py g $CIPHERS)
-    check_translation $? "$T"
-    G_CIPHERS="$G_CIPHERS $T"
 }
 
 # Ciphersuites usable only with Mbed TLS (not currently supported by another
-# peer usable in this script). This provide only very rudimentaty testing, as
+# peer usable in this script). This provides only very rudimentaty testing, as
 # this is not interop testing, but it's better than nothing.
 add_mbedtls_ciphersuites()
 {
@@ -503,48 +498,48 @@
 
         "ECDSA")
             M_CIPHERS="$M_CIPHERS                               \
-                TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256         \
-                TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256         \
-                TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384         \
-                TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384         \
-                TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256     \
-                TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256     \
-                TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384     \
-                TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384     \
-                TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256        \
-                TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384        \
+                TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256         \
+                TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256         \
+                TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384         \
+                TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384         \
+                TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256     \
+                TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256     \
+                TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384     \
+                TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384     \
+                TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256        \
+                TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384        \
                 "
             ;;
 
         "RSA")
             M_CIPHERS="$M_CIPHERS                               \
-                TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256            \
-                TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384            \
-                TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256          \
-                TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384          \
-                TLS-RSA-WITH-ARIA-128-CBC-SHA256                \
-                TLS-RSA-WITH-ARIA-256-CBC-SHA384                \
+                TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256            \
+                TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384            \
+                TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256          \
+                TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384          \
+                TLS_RSA_WITH_ARIA_128_CBC_SHA256                \
+                TLS_RSA_WITH_ARIA_256_CBC_SHA384                \
                 "
             ;;
 
         "PSK")
-            # *PSK-NULL-SHA suites supported by GnuTLS 3.3.5 but not 3.2.15
+            # *PSK_NULL_SHA suites supported by GnuTLS 3.3.5 but not 3.2.15
             M_CIPHERS="$M_CIPHERS                               \
-                TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256            \
-                TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384            \
-                TLS-DHE-PSK-WITH-NULL-SHA                       \
-                TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256          \
-                TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384          \
-                TLS-ECDHE-PSK-WITH-NULL-SHA                     \
-                TLS-PSK-WITH-ARIA-128-CBC-SHA256                \
-                TLS-PSK-WITH-ARIA-256-CBC-SHA384                \
-                TLS-PSK-WITH-NULL-SHA                           \
-                TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256            \
-                TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256            \
-                TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384            \
-                TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384            \
-                TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256       \
-                TLS-RSA-PSK-WITH-NULL-SHA                       \
+                TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256            \
+                TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384            \
+                TLS_DHE_PSK_WITH_NULL_SHA                       \
+                TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256          \
+                TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384          \
+                TLS_ECDHE_PSK_WITH_NULL_SHA                     \
+                TLS_PSK_WITH_ARIA_128_CBC_SHA256                \
+                TLS_PSK_WITH_ARIA_256_CBC_SHA384                \
+                TLS_PSK_WITH_NULL_SHA                           \
+                TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256            \
+                TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256            \
+                TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384            \
+                TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384            \
+                TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256       \
+                TLS_RSA_PSK_WITH_NULL_SHA                       \
                 "
             ;;
     esac
@@ -684,7 +679,11 @@
 
 # is_mbedtls <cmd_line>
 is_mbedtls() {
-    echo "$1" | grep 'ssl_server2\|ssl_client2' > /dev/null
+    case $1 in
+        *ssl_client2*) true;;
+        *ssl_server2*) true;;
+        *) false;;
+    esac
 }
 
 # has_mem_err <log_file_name>
@@ -803,16 +802,14 @@
     echo "EXIT: $EXIT" >> $CLI_OUT
 }
 
-# run_client <name> <cipher>
+# run_client PROGRAM_NAME STANDARD_CIPHER_SUITE PROGRAM_CIPHER_SUITE
 run_client() {
     # announce what we're going to do
     TESTS=$(( $TESTS + 1 ))
-    VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
-    TITLE="`echo $1 | head -c1`->`echo $SERVER_NAME | head -c1`"
+    TITLE="${1%"${1#?}"}->${SERVER_NAME%"${SERVER_NAME#?}"}"
     TITLE="$TITLE $MODE,$VERIF $2"
-    printf "%s " "$TITLE"
-    LEN=$(( 72 - `echo "$TITLE" | wc -c` ))
-    for i in `seq 1 $LEN`; do printf '.'; done; printf ' '
+    DOTS72="........................................................................"
+    printf "%s %.*s " "$TITLE" "$((71 - ${#TITLE}))" "$DOTS72"
 
     # should we skip?
     if [ "X$SKIP_NEXT" = "XYES" ]; then
@@ -825,7 +822,7 @@
     # run the command and interpret result
     case $1 in
         [Oo]pen*)
-            CLIENT_CMD="$OPENSSL s_client $O_CLIENT_ARGS -cipher $2"
+            CLIENT_CMD="$OPENSSL s_client $O_CLIENT_ARGS -cipher $3"
             log "$CLIENT_CMD"
             echo "$CLIENT_CMD" > $CLI_OUT
             printf 'GET HTTP/1.0\r\n\r\n' | $CLIENT_CMD >> $CLI_OUT 2>&1 &
@@ -850,7 +847,7 @@
             else
                 G_HOST="localhost"
             fi
-            CLIENT_CMD="$GNUTLS_CLI $G_CLIENT_ARGS --priority $G_PRIO_MODE:$2 $G_HOST"
+            CLIENT_CMD="$GNUTLS_CLI $G_CLIENT_ARGS --priority $G_PRIO_MODE:$3 $G_HOST"
             log "$CLIENT_CMD"
             echo "$CLIENT_CMD" > $CLI_OUT
             printf 'GET HTTP/1.0\r\n\r\n' | $CLIENT_CMD >> $CLI_OUT 2>&1 &
@@ -872,7 +869,7 @@
             ;;
 
         mbed*)
-            CLIENT_CMD="$M_CLI $M_CLIENT_ARGS force_ciphersuite=$2"
+            CLIENT_CMD="$M_CLI $M_CLIENT_ARGS force_ciphersuite=$3"
             if [ "$MEMCHECK" -gt 0 ]; then
                 CLIENT_CMD="valgrind --leak-check=full $CLIENT_CMD"
             fi
@@ -1005,6 +1002,7 @@
 trap cleanup INT TERM HUP
 
 for VERIFY in $VERIFIES; do
+    VERIF=$(echo $VERIFY | tr '[:upper:]' '[:lower:]')
     for MODE in $MODES; do
         for TYPE in $TYPES; do
             for PEER in $PEERS; do
@@ -1035,17 +1033,19 @@
 
                     if [ "X" != "X$M_CIPHERS" ]; then
                         start_server "OpenSSL"
-                        for i in $M_CIPHERS; do
-                            check_openssl_server_bug $i
-                            run_client mbedTLS $i
+                        translate_ciphers m $M_CIPHERS
+                        for i in $ciphers; do
+                            check_openssl_server_bug
+                            run_client mbedTLS ${i%%=*} ${i#*=}
                         done
                         stop_server
                     fi
 
                     if [ "X" != "X$O_CIPHERS" ]; then
                         start_server "mbedTLS"
-                        for i in $O_CIPHERS; do
-                            run_client OpenSSL $i
+                        translate_ciphers o $O_CIPHERS
+                        for i in $ciphers; do
+                            run_client OpenSSL ${i%%=*} ${i#*=}
                         done
                         stop_server
                     fi
@@ -1061,16 +1061,18 @@
 
                     if [ "X" != "X$M_CIPHERS" ]; then
                         start_server "GnuTLS"
-                        for i in $M_CIPHERS; do
-                            run_client mbedTLS $i
+                        translate_ciphers m $M_CIPHERS
+                        for i in $ciphers; do
+                            run_client mbedTLS ${i%%=*} ${i#*=}
                         done
                         stop_server
                     fi
 
                     if [ "X" != "X$G_CIPHERS" ]; then
                         start_server "mbedTLS"
-                        for i in $G_CIPHERS; do
-                            run_client GnuTLS $i
+                        translate_ciphers g $G_CIPHERS
+                        for i in $ciphers; do
+                            run_client GnuTLS ${i%%=*} ${i#*=}
                         done
                         stop_server
                     fi
@@ -1088,8 +1090,9 @@
 
                     if [ "X" != "X$M_CIPHERS" ]; then
                         start_server "mbedTLS"
-                        for i in $M_CIPHERS; do
-                            run_client mbedTLS $i
+                        translate_ciphers m $M_CIPHERS
+                        for i in $ciphers; do
+                            run_client mbedTLS ${i%%=*} ${i#*=}
                         done
                         stop_server
                     fi
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index 9c7a95d..cf25426 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -93,6 +93,53 @@
 cert_example_multi.crt: cert_example_multi.csr
 	$(OPENSSL) x509 -req -CA $(test_ca_crt) -CAkey $(test_ca_key_file_rsa) -extfile $(test_ca_config_file) -extensions dns_alt_names -passin "pass:$(test_ca_pwd_rsa)" -set_serial 17 -days 3653 -sha256 -in $< > $@
 
+test_csr_v3_keyUsage.csr.der: rsa_pkcs1_1024_clear.pem
+	$(OPENSSL) req -new -subj '/CN=etcd' -config $(test_ca_config_file) -key rsa_pkcs1_1024_clear.pem -outform DER -out $@ -reqexts csr_ext_v3_keyUsage
+test_csr_v3_subjectAltName.csr.der: rsa_pkcs1_1024_clear.pem
+	$(OPENSSL) req -new -subj '/CN=etcd' -config $(test_ca_config_file) -key rsa_pkcs1_1024_clear.pem -outform DER -out $@ -reqexts csr_ext_v3_subjectAltName
+test_csr_v3_nsCertType.csr.der: rsa_pkcs1_1024_clear.pem
+	$(OPENSSL) req -new -subj '/CN=etcd' -config $(test_ca_config_file) -key rsa_pkcs1_1024_clear.pem -outform DER -out $@ -reqexts csr_ext_v3_nsCertType
+test_csr_v3_all.csr.der: rsa_pkcs1_1024_clear.pem
+	$(OPENSSL) req -new -subj '/CN=etcd' -config $(test_ca_config_file) -key rsa_pkcs1_1024_clear.pem -outform DER -out $@ -reqexts csr_ext_v3_all
+test_csr_v3_all_malformed_extensions_sequence_tag.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/300B0603551D0F040403/200B0603551D0F040403/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_extension_id_tag.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/0603551D0F0404030201/0703551D0F0404030201/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_extension_data_tag.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/040403020102302F0603/050403020102302F0603/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_extension_data_len1.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/040403020102302F0603/040503020102302F0603/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_extension_data_len2.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/040403020102302F0603/040303020102302F0603/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_extension_key_usage_bitstream_tag.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/03020102302F0603551D/04020102302F0603551D/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_extension_subject_alt_name_sequence_tag.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/3026A02406082B060105/4026A02406082B060105/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_extension_ns_cert_bitstream_tag.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/03020780300D06092A86/04020780300D06092A86/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_duplicated_extension.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/551D11/551D0F/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_extension_type_oid.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/551D11/551DFF/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_attributes_sequence_tag.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/306006092A864886F70D/406006092A864886F70D/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_attributes_id_tag.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/06092A864886F70D0109/07092A864886F70D0109/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_attributes_extension_request.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/2A864886F70D01090E/2A864886F70D01090F/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_attributes_extension_request_set_tag.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/31533051300B0603551D/32533051300B0603551D/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_attributes_extension_request_sequence_tag.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/3051300B0603551D0F04/3151300B0603551D0F04/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_attributes_len1.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/306006092A864886F70D/306106092A864886F70D/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_attributes_len2.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/306006092A864886F70D/305906092A864886F70D/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_attributes_extension_request_sequence_len1.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/3051300B0603551D0F04/3052300B0603551D0F04/" | xxd -r -p ) > $@
+test_csr_v3_all_malformed_attributes_extension_request_sequence_len2.csr.der: test_csr_v3_all.csr.der
+	(hexdump -ve '1/1 "%.2X"' $< | sed "s/3051300B0603551D0F04/3050300B0603551D0F04/" | xxd -r -p ) > $@
+
 $(test_ca_key_file_rsa_alt):test-ca.opensslconf
 	$(OPENSSL) genrsa -out $@ 2048
 test-ca-alt.csr: $(test_ca_key_file_rsa_alt) $(test_ca_config_file)
diff --git a/tests/data_files/test-ca.opensslconf b/tests/data_files/test-ca.opensslconf
index b2c2fa1..bd12760 100644
--- a/tests/data_files/test-ca.opensslconf
+++ b/tests/data_files/test-ca.opensslconf
@@ -82,3 +82,17 @@
 # these IPs are the ascii values for 'abcd' and 'abcd.example.com'
 [tricky_ip_san]
 subjectAltName=IP:97.98.99.100,IP:6162:6364:2e65:7861:6d70:6c65:2e63:6f6d
+
+[csr_ext_v3_keyUsage]
+keyUsage = digitalSignature, keyEncipherment
+
+[csr_ext_v3_subjectAltName]
+subjectAltName=DNS:example.com, DNS:example.net, DNS:*.example.org
+
+[csr_ext_v3_nsCertType]
+nsCertType=server
+
+[csr_ext_v3_all]
+keyUsage = cRLSign
+subjectAltName=otherName:1.3.6.1.5.5.7.8.4;SEQ:nonprintable_hw_module_name
+nsCertType=client
diff --git a/tests/data_files/test_csr_v3_all.csr.der b/tests/data_files/test_csr_v3_all.csr.der
new file mode 100644
index 0000000..7e717f3
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request.csr.der b/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request.csr.der
new file mode 100644
index 0000000..96a11e8
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_len1.csr.der b/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_len1.csr.der
new file mode 100644
index 0000000..f61c7c8
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_len1.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_len2.csr.der b/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_len2.csr.der
new file mode 100644
index 0000000..e6db2cc
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_len2.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_tag.csr.der b/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_tag.csr.der
new file mode 100644
index 0000000..620fa7d
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_tag.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_set_tag.csr.der b/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_set_tag.csr.der
new file mode 100644
index 0000000..1d358e5
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_attributes_extension_request_set_tag.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_attributes_id_tag.csr.der b/tests/data_files/test_csr_v3_all_malformed_attributes_id_tag.csr.der
new file mode 100644
index 0000000..f8d0689
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_attributes_id_tag.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_attributes_len1.csr.der b/tests/data_files/test_csr_v3_all_malformed_attributes_len1.csr.der
new file mode 100644
index 0000000..01eabff
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_attributes_len1.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_attributes_len2.csr.der b/tests/data_files/test_csr_v3_all_malformed_attributes_len2.csr.der
new file mode 100644
index 0000000..875db76
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_attributes_len2.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_attributes_sequence_tag.csr.der b/tests/data_files/test_csr_v3_all_malformed_attributes_sequence_tag.csr.der
new file mode 100644
index 0000000..38273ca
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_attributes_sequence_tag.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_duplicated_extension.csr.der b/tests/data_files/test_csr_v3_all_malformed_duplicated_extension.csr.der
new file mode 100644
index 0000000..4e2a221
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_duplicated_extension.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_extension_data_len1.csr.der b/tests/data_files/test_csr_v3_all_malformed_extension_data_len1.csr.der
new file mode 100644
index 0000000..6116118
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_extension_data_len1.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_extension_data_len2.csr.der b/tests/data_files/test_csr_v3_all_malformed_extension_data_len2.csr.der
new file mode 100644
index 0000000..a49209a
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_extension_data_len2.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_extension_data_tag.csr.der b/tests/data_files/test_csr_v3_all_malformed_extension_data_tag.csr.der
new file mode 100644
index 0000000..ccae723
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_extension_data_tag.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_extension_id_tag.csr.der b/tests/data_files/test_csr_v3_all_malformed_extension_id_tag.csr.der
new file mode 100644
index 0000000..989e404
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_extension_id_tag.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_extension_key_usage_bitstream_tag.csr.der b/tests/data_files/test_csr_v3_all_malformed_extension_key_usage_bitstream_tag.csr.der
new file mode 100644
index 0000000..a6fd2d7
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_extension_key_usage_bitstream_tag.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_extension_ns_cert_bitstream_tag.csr.der b/tests/data_files/test_csr_v3_all_malformed_extension_ns_cert_bitstream_tag.csr.der
new file mode 100644
index 0000000..6fdcfc8
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_extension_ns_cert_bitstream_tag.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_extension_subject_alt_name_sequence_tag.csr.der b/tests/data_files/test_csr_v3_all_malformed_extension_subject_alt_name_sequence_tag.csr.der
new file mode 100644
index 0000000..f1090f9
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_extension_subject_alt_name_sequence_tag.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_extension_type_oid.csr.der b/tests/data_files/test_csr_v3_all_malformed_extension_type_oid.csr.der
new file mode 100644
index 0000000..36bc61e
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_extension_type_oid.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_all_malformed_extensions_sequence_tag.csr.der b/tests/data_files/test_csr_v3_all_malformed_extensions_sequence_tag.csr.der
new file mode 100644
index 0000000..fecb15e
--- /dev/null
+++ b/tests/data_files/test_csr_v3_all_malformed_extensions_sequence_tag.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_keyUsage.csr.der b/tests/data_files/test_csr_v3_keyUsage.csr.der
new file mode 100644
index 0000000..f8be020
--- /dev/null
+++ b/tests/data_files/test_csr_v3_keyUsage.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_nsCertType.csr.der b/tests/data_files/test_csr_v3_nsCertType.csr.der
new file mode 100644
index 0000000..cf9588d
--- /dev/null
+++ b/tests/data_files/test_csr_v3_nsCertType.csr.der
Binary files differ
diff --git a/tests/data_files/test_csr_v3_subjectAltName.csr.der b/tests/data_files/test_csr_v3_subjectAltName.csr.der
new file mode 100644
index 0000000..2ccb3bb
--- /dev/null
+++ b/tests/data_files/test_csr_v3_subjectAltName.csr.der
Binary files differ
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index eeded5f..2cdcbf1 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -61,24 +61,32 @@
             # fixed this branch to have full coverage of test cases.
             results.warning('Test case not executed: {}', key)
 
-def analyze_driver_vs_reference(outcomes, component_ref, component_driver, ignored_tests):
+def analyze_driver_vs_reference(outcomes, component_ref, component_driver,
+                                ignored_suites, ignored_test=None):
     """Check that all tests executed in the reference component are also
     executed in the corresponding driver component.
-    Skip test suites provided in ignored_tests list.
+    Skip:
+    - full test suites provided in ignored_suites list
+    - only some specific test inside a test suite, for which the corresponding
+      output string is provided
     """
     available = check_test_cases.collect_available_test_cases()
     result = True
 
     for key in available:
-        # Skip ignored test suites
-        test_suite = key.split(';')[0] # retrieve test suit name
-        test_suite = test_suite.split('.')[0] # retrieve main part of test suit name
-        if test_suite in ignored_tests:
-            continue
         # Continue if test was not executed by any component
         hits = outcomes[key].hits() if key in outcomes else 0
         if hits == 0:
             continue
+        # Skip ignored test suites
+        full_test_suite = key.split(';')[0] # retrieve full test suite name
+        test_string = key.split(';')[1] # retrieve the text string of this test
+        test_suite = full_test_suite.split('.')[0] # retrieve main part of test suite name
+        if test_suite in ignored_suites:
+            continue
+        if ((full_test_suite in ignored_test) and
+                (test_string in ignored_test[full_test_suite])):
+            continue
         # Search for tests that run in reference component and not in driver component
         driver_test_passed = False
         reference_test_passed = False
@@ -129,13 +137,14 @@
 
 def do_analyze_driver_vs_reference(outcome_file, args):
     """Perform driver vs reference analyze."""
-    ignored_tests = ['test_suite_' + x for x in args['ignored_suites']]
+    ignored_suites = ['test_suite_' + x for x in args['ignored_suites']]
 
     outcomes = read_outcome_file(outcome_file)
     print("\n*** Analyze driver {} vs reference {} ***\n".format(
         args['component_driver'], args['component_ref']))
     return analyze_driver_vs_reference(outcomes, args['component_ref'],
-                                       args['component_driver'], ignored_tests)
+                                       args['component_driver'], ignored_suites,
+                                       args['ignored_tests'])
 
 # List of tasks with a function that can handle this task and additional arguments if required
 TASKS = {
@@ -154,7 +163,11 @@
             'ignored_suites': [
                 'shax', 'mdx', # the software implementations that are being excluded
                 'md',  # the legacy abstraction layer that's being excluded
-            ]}},
+            ],
+            'ignored_tests': {
+            }
+        }
+    },
     'analyze_driver_vs_reference_ecdsa': {
         'test_function': do_analyze_driver_vs_reference,
         'args': {
@@ -164,15 +177,19 @@
                 'ecdsa', # the software implementation that's excluded
                 # the following lines should not be needed,
                 # they will be removed by upcoming work
-                'psa_crypto_se_driver_hal', # #6856
-                'random', # #6856
-                'ecp', # #6856
                 'pk', # #6857
                 'x509parse', # #6858
                 'x509write', # #6858
                 'debug', # #6860
                 'ssl', # #6860
-            ]}},
+            ],
+            'ignored_tests': {
+                'test_suite_random': [
+                    'PSA classic wrapper: ECDSA signature (SECP256R1)',
+                ],
+            }
+        }
+    },
 }
 
 def main():
diff --git a/tests/scripts/check_files.py b/tests/scripts/check_files.py
index d20ec2e..352b55e 100755
--- a/tests/scripts/check_files.py
+++ b/tests/scripts/check_files.py
@@ -268,7 +268,7 @@
 
     heading = "Invalid UTF-8 or forbidden character:"
 
-    # Only allow valid UTF-8, and only white-listed characters.
+    # Only allow valid UTF-8, and only other explicitly allowed characters.
     # We deliberately exclude all characters that aren't a simple non-blank,
     # non-zero-width glyph, apart from a very small set (tab, ordinary space,
     # line breaks, "basic" no-break space and soft hyphen). In particular,
@@ -285,6 +285,7 @@
         '\u2070\u2071\u2074-\u208E\u2090-\u209C', # Superscripts and Subscripts
         '\u2190-\u21FF', # Arrows
         '\u2200-\u22FF', # Mathematical Symbols
+        '\u2500-\u257F' # Box Drawings characters used in markdown trees
     ])
     # Allow any of the characters and ranges above, and anything classified
     # as a word constituent.
diff --git a/tests/scripts/translate_ciphers.py b/tests/scripts/translate_ciphers.py
index d5f847f..a8db4bb 100755
--- a/tests/scripts/translate_ciphers.py
+++ b/tests/scripts/translate_ciphers.py
@@ -18,8 +18,7 @@
 # limitations under the License.
 
 """
-Translate ciphersuite names in Mbed TLS format to OpenSSL and GNUTLS
-standards.
+Translate standard ciphersuite names to GnuTLS, OpenSSL and Mbed TLS standards.
 
 To test the translation functions run:
 python3 -m unittest translate_cipher.py
@@ -36,124 +35,158 @@
     """
     def test_translate_all_cipher_names(self):
         """
-        Translate MbedTLS ciphersuite names to their OpenSSL and
-        GnuTLS counterpart. Use only a small subset of ciphers
-        that exercise each step of the translate functions
+        Translate standard ciphersuite names to GnuTLS, OpenSSL and
+        Mbed TLS counterpart. Use only a small subset of ciphers
+        that exercise each step of the translation functions
         """
         ciphers = [
-            ("TLS-ECDHE-ECDSA-WITH-NULL-SHA",
+            ("TLS_ECDHE_ECDSA_WITH_NULL_SHA",
              "+ECDHE-ECDSA:+NULL:+SHA1",
-             "ECDHE-ECDSA-NULL-SHA"),
-            ("TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
+             "ECDHE-ECDSA-NULL-SHA",
+             "TLS-ECDHE-ECDSA-WITH-NULL-SHA"),
+            ("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
              "+ECDHE-ECDSA:+AES-128-GCM:+AEAD",
-             "ECDHE-ECDSA-AES128-GCM-SHA256"),
-            ("TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
+             "ECDHE-ECDSA-AES128-GCM-SHA256",
+             "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256"),
+            ("TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
              "+DHE-RSA:+3DES-CBC:+SHA1",
-             "EDH-RSA-DES-CBC3-SHA"),
-            ("TLS-RSA-WITH-AES-256-CBC-SHA",
+             "EDH-RSA-DES-CBC3-SHA",
+             "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA"),
+            ("TLS_RSA_WITH_AES_256_CBC_SHA",
              "+RSA:+AES-256-CBC:+SHA1",
-             "AES256-SHA"),
-            ("TLS-PSK-WITH-3DES-EDE-CBC-SHA",
+             "AES256-SHA",
+             "TLS-RSA-WITH-AES-256-CBC-SHA"),
+            ("TLS_PSK_WITH_3DES_EDE_CBC_SHA",
              "+PSK:+3DES-CBC:+SHA1",
-             "PSK-3DES-EDE-CBC-SHA"),
-            ("TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
+             "PSK-3DES-EDE-CBC-SHA",
+             "TLS-PSK-WITH-3DES-EDE-CBC-SHA"),
+            ("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
              None,
-             "ECDHE-ECDSA-CHACHA20-POLY1305"),
-            ("TLS-ECDHE-ECDSA-WITH-AES-128-CCM",
+             "ECDHE-ECDSA-CHACHA20-POLY1305",
+             "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256"),
+            ("TLS_ECDHE_ECDSA_WITH_AES_128_CCM",
              "+ECDHE-ECDSA:+AES-128-CCM:+AEAD",
-             None),
-            ("TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384",
              None,
-             "ECDHE-ARIA256-GCM-SHA384"),
+             "TLS-ECDHE-ECDSA-WITH-AES-128-CCM"),
+            ("TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384",
+             None,
+             "ECDHE-ARIA256-GCM-SHA384",
+             "TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384"),
         ]
 
-        for m, g_exp, o_exp in ciphers:
+        for s, g_exp, o_exp, m_exp in ciphers:
 
             if g_exp is not None:
-                g = translate_gnutls(m)
+                g = translate_gnutls(s)
                 self.assertEqual(g, g_exp)
 
             if o_exp is not None:
-                o = translate_ossl(m)
+                o = translate_ossl(s)
                 self.assertEqual(o, o_exp)
 
-def translate_gnutls(m_cipher):
+            if m_exp is not None:
+                m = translate_mbedtls(s)
+                self.assertEqual(m, m_exp)
+
+def translate_gnutls(s_cipher):
     """
-    Translate m_cipher from Mbed TLS ciphersuite naming convention
+    Translate s_cipher from standard ciphersuite naming convention
     and return the GnuTLS naming convention
     """
 
-    m_cipher = re.sub(r'\ATLS-', '+', m_cipher)
-    m_cipher = m_cipher.replace("-WITH-", ":+")
-    m_cipher = m_cipher.replace("-EDE", "")
+    # Replace "_" with "-" to handle ciphersuite names based on Mbed TLS
+    # naming convention
+    s_cipher = s_cipher.replace("_", "-")
+
+    s_cipher = re.sub(r'\ATLS-', '+', s_cipher)
+    s_cipher = s_cipher.replace("-WITH-", ":+")
+    s_cipher = s_cipher.replace("-EDE", "")
 
     # SHA in Mbed TLS == SHA1 GnuTLS,
     # if the last 3 chars are SHA append 1
-    if m_cipher[-3:] == "SHA":
-        m_cipher = m_cipher+"1"
+    if s_cipher[-3:] == "SHA":
+        s_cipher = s_cipher+"1"
 
     # CCM or CCM-8 should be followed by ":+AEAD"
     # Replace "GCM:+SHAxyz" with "GCM:+AEAD"
-    if "CCM" in m_cipher or "GCM" in m_cipher:
-        m_cipher = re.sub(r"GCM-SHA\d\d\d", "GCM", m_cipher)
-        m_cipher = m_cipher+":+AEAD"
+    if "CCM" in s_cipher or "GCM" in s_cipher:
+        s_cipher = re.sub(r"GCM-SHA\d\d\d", "GCM", s_cipher)
+        s_cipher = s_cipher+":+AEAD"
 
     # Replace the last "-" with ":+"
     else:
-        index = m_cipher.rindex("-")
-        m_cipher = m_cipher[:index] + ":+" + m_cipher[index+1:]
+        index = s_cipher.rindex("-")
+        s_cipher = s_cipher[:index] + ":+" + s_cipher[index+1:]
 
-    return m_cipher
+    return s_cipher
 
-def translate_ossl(m_cipher):
+def translate_ossl(s_cipher):
     """
-    Translate m_cipher from Mbed TLS ciphersuite naming convention
+    Translate s_cipher from standard ciphersuite naming convention
     and return the OpenSSL naming convention
     """
 
-    m_cipher = re.sub(r'^TLS-', '', m_cipher)
-    m_cipher = m_cipher.replace("-WITH", "")
+    # Replace "_" with "-" to handle ciphersuite names based on Mbed TLS
+    # naming convention
+    s_cipher = s_cipher.replace("_", "-")
+
+    s_cipher = re.sub(r'^TLS-', '', s_cipher)
+    s_cipher = s_cipher.replace("-WITH", "")
 
     # Remove the "-" from "ABC-xyz"
-    m_cipher = m_cipher.replace("AES-", "AES")
-    m_cipher = m_cipher.replace("CAMELLIA-", "CAMELLIA")
-    m_cipher = m_cipher.replace("ARIA-", "ARIA")
+    s_cipher = s_cipher.replace("AES-", "AES")
+    s_cipher = s_cipher.replace("CAMELLIA-", "CAMELLIA")
+    s_cipher = s_cipher.replace("ARIA-", "ARIA")
 
     # Remove "RSA" if it is at the beginning
-    m_cipher = re.sub(r'^RSA-', r'', m_cipher)
+    s_cipher = re.sub(r'^RSA-', r'', s_cipher)
 
     # For all circumstances outside of PSK
-    if "PSK" not in m_cipher:
-        m_cipher = m_cipher.replace("-EDE", "")
-        m_cipher = m_cipher.replace("3DES-CBC", "DES-CBC3")
+    if "PSK" not in s_cipher:
+        s_cipher = s_cipher.replace("-EDE", "")
+        s_cipher = s_cipher.replace("3DES-CBC", "DES-CBC3")
 
         # Remove "CBC" if it is not prefixed by DES
-        m_cipher = re.sub(r'(?<!DES-)CBC-', r'', m_cipher)
+        s_cipher = re.sub(r'(?<!DES-)CBC-', r'', s_cipher)
 
     # ECDHE-RSA-ARIA does not exist in OpenSSL
-    m_cipher = m_cipher.replace("ECDHE-RSA-ARIA", "ECDHE-ARIA")
+    s_cipher = s_cipher.replace("ECDHE-RSA-ARIA", "ECDHE-ARIA")
 
     # POLY1305 should not be followed by anything
-    if "POLY1305" in m_cipher:
-        index = m_cipher.rindex("POLY1305")
-        m_cipher = m_cipher[:index+8]
+    if "POLY1305" in s_cipher:
+        index = s_cipher.rindex("POLY1305")
+        s_cipher = s_cipher[:index+8]
 
     # If DES is being used, Replace DHE with EDH
-    if "DES" in m_cipher and "DHE" in m_cipher and "ECDHE" not in m_cipher:
-        m_cipher = m_cipher.replace("DHE", "EDH")
+    if "DES" in s_cipher and "DHE" in s_cipher and "ECDHE" not in s_cipher:
+        s_cipher = s_cipher.replace("DHE", "EDH")
 
-    return m_cipher
+    return s_cipher
+
+def translate_mbedtls(s_cipher):
+    """
+    Translate s_cipher from standard ciphersuite naming convention
+    and return Mbed TLS ciphersuite naming convention
+    """
+
+    # Replace "_" with "-"
+    s_cipher = s_cipher.replace("_", "-")
+
+    return s_cipher
 
 def format_ciphersuite_names(mode, names):
-    t = {"g": translate_gnutls, "o": translate_ossl}[mode]
-    return " ".join(t(c) for c in names)
+    t = {"g": translate_gnutls,
+         "o": translate_ossl,
+         "m": translate_mbedtls
+        }[mode]
+    return " ".join(c + '=' + t(c) for c in names)
 
 def main(target, names):
     print(format_ciphersuite_names(target, names))
 
 if __name__ == "__main__":
     PARSER = argparse.ArgumentParser()
-    PARSER.add_argument('target', metavar='TARGET', choices=['o', 'g'])
+    PARSER.add_argument('target', metavar='TARGET', choices=['o', 'g', 'm'])
     PARSER.add_argument('names', metavar='NAMES', nargs='+')
     ARGS = PARSER.parse_args()
     main(ARGS.target, ARGS.names)
diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function
index 85c00eb..7d81608 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -284,7 +284,7 @@
     }
     TEST_EQUAL(test_offset_idx, expected_idx);
 
-    /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT).
+    /* Call update with too much data (sizeof(entropy) > MAX(_SEED)_INPUT).
      * Make sure it's detected as an error and doesn't cause memory
      * corruption. */
     TEST_ASSERT(mbedtls_ctr_drbg_update(
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 394253d..c8a0a82 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -811,7 +811,7 @@
 }
 /* END_CASE */
 
-/* BEGIN_CASE depends_on:MBEDTLS_ECDH_C:MBEDTLS_ECDSA_C */
+/* BEGIN_CASE */
 void mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
                                 char *P, char *A, char *B,
                                 char *G_x, char *G_y, char *N,
@@ -903,9 +903,13 @@
 
     // Check curve type, and if it can be used for ECDH/ECDSA
     TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
+#if defined(MBEDTLS_ECDH_C)
     TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
+#endif
+#if defined(MBEDTLS_ECDSA_C)
     TEST_EQUAL(mbedtls_ecdsa_can_do(id),
                crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
+#endif
 
     // Copy group and compare with original
     TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
diff --git a/tests/suites/test_suite_mdx.function b/tests/suites/test_suite_mdx.function
index 93f4101..df94d16 100644
--- a/tests/suites/test_suite_mdx.function
+++ b/tests/suites/test_suite_mdx.function
@@ -10,8 +10,8 @@
     unsigned char src_str[100];
     unsigned char output[16];
 
-    memset(src_str, 0x00, sizeof src_str);
-    memset(output, 0x00, sizeof output);
+    memset(src_str, 0x00, sizeof(src_str));
+    memset(output, 0x00, sizeof(output));
 
     strncpy((char *) src_str, text_src_string, sizeof(src_str) - 1);
 
@@ -19,7 +19,7 @@
     TEST_ASSERT(ret == 0);
 
     TEST_ASSERT(mbedtls_test_hexcmp(output, hash->x,
-                                    sizeof output, hash->len) == 0);
+                                    sizeof(output), hash->len) == 0);
 }
 /* END_CASE */
 
@@ -30,8 +30,8 @@
     unsigned char src_str[100];
     unsigned char output[20];
 
-    memset(src_str, 0x00, sizeof src_str);
-    memset(output, 0x00, sizeof output);
+    memset(src_str, 0x00, sizeof(src_str));
+    memset(output, 0x00, sizeof(output));
 
     strncpy((char *) src_str, text_src_string, sizeof(src_str) - 1);
 
@@ -39,7 +39,7 @@
     TEST_ASSERT(ret == 0);
 
     TEST_ASSERT(mbedtls_test_hexcmp(output, hash->x,
-                                    sizeof output, hash->len) == 0);
+                                    sizeof(output), hash->len) == 0);
 }
 /* END_CASE */
 
diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function
index 13b5162..67d3235 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -726,7 +726,7 @@
 
         slen = sizeof(sig);
         ret = mbedtls_pk_sign_restartable(&prv, md_alg, hash->x, hash->len,
-                                          sig, sizeof sig, &slen,
+                                          sig, sizeof(sig), &slen,
                                           mbedtls_test_rnd_std_rand, NULL,
                                           &rs_ctx);
         TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
@@ -763,15 +763,15 @@
     mbedtls_pk_init(&pk);
     USE_PSA_INIT();
 
-    memset(hash, 0x2a, sizeof hash);
-    memset(sig, 0, sizeof sig);
+    memset(hash, 0x2a, sizeof(hash));
+    memset(sig, 0, sizeof(sig));
 
     TEST_ASSERT(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(type)) == 0);
     TEST_ASSERT(pk_genkey(&pk, parameter) == 0);
 
     TEST_ASSERT(mbedtls_pk_sign_restartable(&pk, MBEDTLS_MD_SHA256,
                                             hash, hash_len,
-                                            sig, sizeof sig, &sig_len,
+                                            sig, sizeof(sig), &sig_len,
                                             mbedtls_test_rnd_std_rand, NULL,
                                             rs_ctx) == sign_ret);
     if (sign_ret == 0) {
@@ -796,7 +796,7 @@
     }
 
     TEST_ASSERT(mbedtls_pk_sign(&pk, MBEDTLS_MD_SHA256, hash, hash_len,
-                                sig, sizeof sig, &sig_len,
+                                sig, sizeof(sig), &sig_len,
                                 mbedtls_test_rnd_std_rand,
                                 NULL) == sign_ret);
     if (sign_ret == 0) {
@@ -811,12 +811,12 @@
     if (verify_ret == 0) {
         hash[0]++;
         TEST_ASSERT(mbedtls_pk_verify_restartable(&pk, MBEDTLS_MD_SHA256,
-                                                  hash, sizeof hash, sig, sig_len, rs_ctx) != 0);
+                                                  hash, sizeof(hash), sig, sig_len, rs_ctx) != 0);
         hash[0]--;
 
         sig[0]++;
         TEST_ASSERT(mbedtls_pk_verify_restartable(&pk, MBEDTLS_MD_SHA256,
-                                                  hash, sizeof hash, sig, sig_len, rs_ctx) != 0);
+                                                  hash, sizeof(hash), sig, sig_len, rs_ctx) != 0);
         sig[0]--;
     }
 
@@ -1068,8 +1068,8 @@
         return;
     }
 
-    memset(hash, 0x2a, sizeof hash);
-    memset(sig, 0, sizeof sig);
+    memset(hash, 0x2a, sizeof(hash));
+    memset(sig, 0, sizeof(sig));
 
     mbedtls_pk_init(&pk);
 
@@ -1086,7 +1086,7 @@
                                   sig, sig_len) == MBEDTLS_ERR_PK_BAD_INPUT_DATA);
 
     TEST_ASSERT(mbedtls_pk_sign(&pk, MBEDTLS_MD_NONE, hash, hash_len,
-                                sig, sizeof sig, &sig_len,
+                                sig, sizeof(sig), &sig_len,
                                 mbedtls_test_rnd_std_rand, NULL)
                 == MBEDTLS_ERR_PK_BAD_INPUT_DATA);
 
@@ -1116,11 +1116,11 @@
     mbedtls_rsa_init(&raw);
     mbedtls_pk_init(&rsa); mbedtls_pk_init(&alt);
 
-    memset(hash, 0x2a, sizeof hash);
-    memset(sig, 0, sizeof sig);
-    memset(msg, 0x2a, sizeof msg);
-    memset(ciph, 0, sizeof ciph);
-    memset(test, 0, sizeof test);
+    memset(hash, 0x2a, sizeof(hash));
+    memset(sig, 0, sizeof(sig));
+    memset(msg, 0x2a, sizeof(msg));
+    memset(ciph, 0, sizeof(ciph));
+    memset(test, 0, sizeof(test));
 
     /* Initialize PK RSA context with random key */
     TEST_ASSERT(mbedtls_pk_setup(&rsa,
@@ -1145,34 +1145,34 @@
     /* Test signature */
 #if SIZE_MAX > UINT_MAX
     TEST_ASSERT(mbedtls_pk_sign(&alt, MBEDTLS_MD_NONE, hash, SIZE_MAX,
-                                sig, sizeof sig, &sig_len,
+                                sig, sizeof(sig), &sig_len,
                                 mbedtls_test_rnd_std_rand, NULL)
                 == MBEDTLS_ERR_PK_BAD_INPUT_DATA);
 #endif /* SIZE_MAX > UINT_MAX */
-    TEST_ASSERT(mbedtls_pk_sign(&alt, MBEDTLS_MD_NONE, hash, sizeof hash,
-                                sig, sizeof sig, &sig_len,
+    TEST_ASSERT(mbedtls_pk_sign(&alt, MBEDTLS_MD_NONE, hash, sizeof(hash),
+                                sig, sizeof(sig), &sig_len,
                                 mbedtls_test_rnd_std_rand, NULL)
                 == 0);
     TEST_ASSERT(sig_len == RSA_KEY_LEN);
     TEST_ASSERT(mbedtls_pk_verify(&rsa, MBEDTLS_MD_NONE,
-                                  hash, sizeof hash, sig, sig_len) == 0);
+                                  hash, sizeof(hash), sig, sig_len) == 0);
 
     /* Test decrypt */
-    TEST_ASSERT(mbedtls_pk_encrypt(&rsa, msg, sizeof msg,
-                                   ciph, &ciph_len, sizeof ciph,
+    TEST_ASSERT(mbedtls_pk_encrypt(&rsa, msg, sizeof(msg),
+                                   ciph, &ciph_len, sizeof(ciph),
                                    mbedtls_test_rnd_std_rand, NULL) == 0);
     TEST_ASSERT(mbedtls_pk_decrypt(&alt, ciph, ciph_len,
-                                   test, &test_len, sizeof test,
+                                   test, &test_len, sizeof(test),
                                    mbedtls_test_rnd_std_rand, NULL) == 0);
-    TEST_ASSERT(test_len == sizeof msg);
+    TEST_ASSERT(test_len == sizeof(msg));
     TEST_ASSERT(memcmp(test, msg, test_len) == 0);
 
     /* Test forbidden operations */
-    TEST_ASSERT(mbedtls_pk_encrypt(&alt, msg, sizeof msg,
-                                   ciph, &ciph_len, sizeof ciph,
+    TEST_ASSERT(mbedtls_pk_encrypt(&alt, msg, sizeof(msg),
+                                   ciph, &ciph_len, sizeof(ciph),
                                    mbedtls_test_rnd_std_rand, NULL) == ret);
     TEST_ASSERT(mbedtls_pk_verify(&alt, MBEDTLS_MD_NONE,
-                                  hash, sizeof hash, sig, sig_len) == ret);
+                                  hash, sizeof(hash), sig, sig_len) == ret);
     TEST_ASSERT(mbedtls_pk_debug(&alt, dbg_items) == ret);
 
 exit:
@@ -1260,11 +1260,11 @@
     TEST_EQUAL(psa_get_key_lifetime(&attributes),
                PSA_KEY_LIFETIME_VOLATILE);
 
-    memset(hash, 0x2a, sizeof hash);
-    memset(sig, 0, sizeof sig);
+    memset(hash, 0x2a, sizeof(hash));
+    memset(sig, 0, sizeof(sig));
 
     TEST_ASSERT(mbedtls_pk_sign(&pk, MBEDTLS_MD_SHA256,
-                                hash, sizeof hash, sig, sizeof sig, &sig_len,
+                                hash, sizeof(hash), sig, sizeof(sig), &sig_len,
                                 NULL, NULL) == 0);
 
     /* Export underlying public key for re-importing in a psa context. */
@@ -1285,7 +1285,7 @@
     TEST_ASSERT(mbedtls_pk_parse_public_key(&pk, pkey_legacy_start,
                                             klen_legacy) == 0);
     TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256,
-                                  hash, sizeof hash, sig, sig_len) == 0);
+                                  hash, sizeof(hash), sig, sig_len) == 0);
 
 exit:
     /*
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.data b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
index 2bcf4e4..22b0570 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.data
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
@@ -178,25 +178,25 @@
 register_key_smoke_test:TEST_SE_PERSISTENT_LIFETIME:7:PSA_KEY_ID_VOLATILE_MAX:1:PSA_ERROR_INVALID_ARGUMENT
 
 Import-sign-verify: sign in driver, ECDSA
-depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_C:PSA_WANT_ECC_SECP_R1_256
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ECC_SECP_R1_256
 sign_verify:SIGN_IN_DRIVER_AND_PARALLEL_CREATION:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):PSA_ALG_ECDSA_ANY:0:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":"54686973206973206e6f74206120686173682e"
 
 Import-sign-verify: sign in driver then export_public, ECDSA
-depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_C:PSA_WANT_ECC_SECP_R1_256
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ECC_SECP_R1_256
 sign_verify:SIGN_IN_DRIVER_THEN_EXPORT_PUBLIC:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):PSA_ALG_ECDSA_ANY:0:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":"54686973206973206e6f74206120686173682e"
 
 Import-sign-verify: sign in software, ECDSA
-depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_C:PSA_WANT_ECC_SECP_R1_256
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ECC_SECP_R1_256
 sign_verify:SIGN_IN_SOFTWARE_AND_PARALLEL_CREATION:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):PSA_ALG_ECDSA_ANY:0:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":"54686973206973206e6f74206120686173682e"
 
 Generate-sign-verify: sign in driver, ECDSA
-depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_C:PSA_WANT_ECC_SECP_R1_256
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ECC_SECP_R1_256
 sign_verify:SIGN_IN_DRIVER_AND_PARALLEL_CREATION:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):PSA_ALG_ECDSA_ANY:256:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":"54686973206973206e6f74206120686173682e"
 
 Generate-sign-verify: sign in driver then export_public, ECDSA
-depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_C:PSA_WANT_ECC_SECP_R1_256
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ECC_SECP_R1_256
 sign_verify:SIGN_IN_DRIVER_THEN_EXPORT_PUBLIC:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):PSA_ALG_ECDSA_ANY:256:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":"54686973206973206e6f74206120686173682e"
 
 Generate-sign-verify: sign in software, ECDSA
-depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_C:PSA_WANT_ECC_SECP_R1_256
+depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ECC_SECP_R1_256
 sign_verify:SIGN_IN_SOFTWARE_AND_PARALLEL_CREATION:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ):PSA_ALG_ECDSA_ANY:256:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":"54686973206973206e6f74206120686173682e"
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 002f3dc..6821fe1 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -308,48 +308,64 @@
 
 X509 CSR Information EC with SHA1
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_info:"data_files/server5.req.sha1":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA1\nEC key size   \: 256 bits\n"
+mbedtls_x509_csr_info:"data_files/server5.req.sha1":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA1\nEC key size   \: 256 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n"
 
 X509 CSR Information EC with SHA224
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_224_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_info:"data_files/server5.req.sha224":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA224\nEC key size   \: 256 bits\n"
+mbedtls_x509_csr_info:"data_files/server5.req.sha224":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA224\nEC key size   \: 256 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n"
 
 X509 CSR Information EC with SHA256
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_info:"data_files/server5.req.sha256":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA256\nEC key size   \: 256 bits\n"
+mbedtls_x509_csr_info:"data_files/server5.req.sha256":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA256\nEC key size   \: 256 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n"
 
 X509 CSR Information EC with SHA384
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_info:"data_files/server5.req.sha384":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA384\nEC key size   \: 256 bits\n"
+mbedtls_x509_csr_info:"data_files/server5.req.sha384":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA384\nEC key size   \: 256 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n"
 
 X509 CSR Information EC with SHA512
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_info:"data_files/server5.req.sha512":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA512\nEC key size   \: 256 bits\n"
+mbedtls_x509_csr_info:"data_files/server5.req.sha512":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA512\nEC key size   \: 256 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n"
 
 X509 CSR Information RSA-PSS with SHA1
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_info:"data_files/server9.req.sha1":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA1, MGF1-SHA1, 0x6A)\nRSA key size  \: 1024 bits\n"
+mbedtls_x509_csr_info:"data_files/server9.req.sha1":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA1, MGF1-SHA1, 0x6A)\nRSA key size  \: 1024 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n"
 
 X509 CSR Information RSA-PSS with SHA224
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_HAS_ALG_SHA_224_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_info:"data_files/server9.req.sha224":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA224, MGF1-SHA224, 0x62)\nRSA key size  \: 1024 bits\n"
+mbedtls_x509_csr_info:"data_files/server9.req.sha224":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA224, MGF1-SHA224, 0x62)\nRSA key size  \: 1024 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n"
 
 X509 CSR Information RSA-PSS with SHA256
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_info:"data_files/server9.req.sha256":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA256, MGF1-SHA256, 0x5E)\nRSA key size  \: 1024 bits\n"
+mbedtls_x509_csr_info:"data_files/server9.req.sha256":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA256, MGF1-SHA256, 0x5E)\nRSA key size  \: 1024 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n"
 
 X509 CSR Information RSA-PSS with SHA384
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_info:"data_files/server9.req.sha384":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA384, MGF1-SHA384, 0x4E)\nRSA key size  \: 1024 bits\n"
+mbedtls_x509_csr_info:"data_files/server9.req.sha384":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA384, MGF1-SHA384, 0x4E)\nRSA key size  \: 1024 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n"
 
 X509 CSR Information RSA-PSS with SHA512
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_HAS_ALG_SHA_512_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_info:"data_files/server9.req.sha512":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA512, MGF1-SHA512, 0x3E)\nRSA key size  \: 1024 bits\n"
+mbedtls_x509_csr_info:"data_files/server9.req.sha512":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: RSASSA-PSS (SHA512, MGF1-SHA512, 0x3E)\nRSA key size  \: 1024 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n"
 
 X509 CSR Information RSA with SHA-256 - Microsoft header
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
 mbedtls_x509_csr_info:"data_files/server1-ms.req.sha256":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nsigned using  \: RSA with SHA-256\nRSA key size  \: 2048 bits\n"
 
+X509 CSR Information v3 extensions #1 (all)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:!MBEDTLS_X509_REMOVE_INFO
+mbedtls_x509_csr_info:"data_files/test_csr_v3_all.csr.der":"CSR version   \: 1\nsubject name  \: CN=etcd\nsigned using  \: RSA with SHA-256\nRSA key size  \: 1024 bits\n\nsubject alt name  \:\n    otherName \:\n        hardware module name \:\n            hardware type          \: 1.3.6.1.4.1.17.3\n            hardware serial number \: 3132338081008180333231\ncert. type        \: SSL Client\nkey usage         \: CRL Sign\n"
+
+X509 CSR Information v3 extensions #2 (nsCertType only)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:!MBEDTLS_X509_REMOVE_INFO
+mbedtls_x509_csr_info:"data_files/test_csr_v3_nsCertType.csr.der":"CSR version   \: 1\nsubject name  \: CN=etcd\nsigned using  \: RSA with SHA-256\nRSA key size  \: 1024 bits\n\ncert. type        \: SSL Server\n"
+
+X509 CSR Information v3 extensions #3 (subjectAltName only)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:!MBEDTLS_X509_REMOVE_INFO
+mbedtls_x509_csr_info:"data_files/test_csr_v3_subjectAltName.csr.der":"CSR version   \: 1\nsubject name  \: CN=etcd\nsigned using  \: RSA with SHA-256\nRSA key size  \: 1024 bits\n\nsubject alt name  \:\n    dNSName \: example.com\n    dNSName \: example.net\n    dNSName \: *.example.org\n"
+
+X509 CSR Information v3 extensions #4 (keyUsage only)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:!MBEDTLS_X509_REMOVE_INFO
+mbedtls_x509_csr_info:"data_files/test_csr_v3_keyUsage.csr.der":"CSR version   \: 1\nsubject name  \: CN=etcd\nsigned using  \: RSA with SHA-256\nRSA key size  \: 1024 bits\n\nkey usage         \: Digital Signature, Key Encipherment\n"
+
 X509 Verify Information: empty
 x509_verify_info:0:"":""
 
@@ -2573,7 +2589,7 @@
 
 X509 CSR ASN.1 (OK)
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:!MBEDTLS_X509_REMOVE_INFO
-mbedtls_x509_csr_parse:"308201183081bf0201003034310b3009060355040613024e4c3111300f060355040a1308506f6c617253534c31123010060355040313096c6f63616c686f73743059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa029302706092a864886f70d01090e311a301830090603551d1304023000300b0603551d0f0404030205e0300906072a8648ce3d04010349003046022100b49fd8c8f77abfa871908dfbe684a08a793d0f490a43d86fcf2086e4f24bb0c2022100f829d5ccd3742369299e6294394717c4b723a0f68b44e831b6e6c3bcabf97243":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA1\nEC key size   \: 256 bits\n":0
+mbedtls_x509_csr_parse:"308201183081bf0201003034310b3009060355040613024e4c3111300f060355040a1308506f6c617253534c31123010060355040313096c6f63616c686f73743059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa029302706092a864886f70d01090e311a301830090603551d1304023000300b0603551d0f0404030205e0300906072a8648ce3d04010349003046022100b49fd8c8f77abfa871908dfbe684a08a793d0f490a43d86fcf2086e4f24bb0c2022100f829d5ccd3742369299e6294394717c4b723a0f68b44e831b6e6c3bcabf97243":"CSR version   \: 1\nsubject name  \: C=NL, O=PolarSSL, CN=localhost\nsigned using  \: ECDSA with SHA1\nEC key size   \: 256 bits\n\nkey usage         \: Digital Signature, Non Repudiation, Key Encipherment\n":0
 
 X509 CSR ASN.1 (bad first tag)
 mbedtls_x509_csr_parse:"3100":"":MBEDTLS_ERR_X509_INVALID_FORMAT
@@ -2664,6 +2680,84 @@
 X509 CSR ASN.1 (invalid version overflow)
 mbedtls_x509_csr_parse:"3008300602047fffffff":"":MBEDTLS_ERR_X509_UNKNOWN_VERSION
 
+# Used test_csr_v3_all.csr.der as a base for malforming CSR extenstions/attributes
+# Please see makefile for data_files to check malformation details (test_csr_v3_all_malformed_xxx.csr files)
+X509 CSR ASN.1 (attributes: invalid sequence tag)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_attributes_sequence_tag.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (attributes: invalid attribute id)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_attributes_id_tag.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (attributes: not extension request)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_attributes_extension_request.csr.der":"CSR version   \: 1\nsubject name  \: CN=etcd\nsigned using  \: RSA with SHA-256\nRSA key size  \: 1024 bits\n":0
+
+X509 CSR ASN.1 (attributes: invalid extenstion request set tag)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_attributes_extension_request_set_tag.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (attributes: invalid extenstion request sequence tag)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_tag.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (attributes: invalid len (len > data))
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_attributes_len1.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (attributes: invalid len (len < data))
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_attributes_len2.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
+
+X509 CSR ASN.1 (attributes: extension request invalid len (len > data))
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_len1.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (attributes: extension request invalid len (len < data))
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_attributes_extension_request_sequence_len2.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (extensions: invalid sequence tag)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_extensions_sequence_tag.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (extensions: invalid extension id tag)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_extension_id_tag.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (extensions: invalid extension data tag)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_extension_data_tag.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (extensions: invalid extension data len (len > data))
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_extension_data_len1.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+X509 CSR ASN.1 (extensions: invalid extension data len (len < data))
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_extension_data_len2.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
+
+X509 CSR ASN.1 (extensions: invalid extension key usage bitstream tag)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_extension_key_usage_bitstream_tag.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (extensions: invalid extension subject alt name sequence tag)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_extension_subject_alt_name_sequence_tag.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (extensions: invalid extension ns cert bitstream tag)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_extension_ns_cert_bitstream_tag.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+X509 CSR ASN.1 (extensions: duplicated extension)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_duplicated_extension.csr.der":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_INVALID_DATA
+
+X509 CSR ASN.1 (extensions: invalid extension type data)
+depends_on:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
+mbedtls_x509_csr_parse_file:"data_files/test_csr_v3_all_malformed_extension_type_oid.csr.der":"CSR version   \: 1\nsubject name  \: CN=etcd\nsigned using  \: RSA with SHA-256\nRSA key size  \: 1024 bits\n\ncert. type        \: SSL Client\nkey usage         \: CRL Sign\n":0
+
 X509 File parse (no issues)
 depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C
 x509parse_crt_file:"data_files/server7_int-ca.crt":0
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 5d896bf..7e68d1e 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -1169,6 +1169,30 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CSR_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
+void mbedtls_x509_csr_parse_file(char *csr_file, char *ref_out, int ref_ret)
+{
+    mbedtls_x509_csr csr;
+    char my_out[1000];
+    int my_ret;
+
+    mbedtls_x509_csr_init(&csr);
+    memset(my_out, 0, sizeof(my_out));
+
+    my_ret = mbedtls_x509_csr_parse_file(&csr, csr_file);
+    TEST_ASSERT(my_ret == ref_ret);
+
+    if (ref_ret == 0) {
+        size_t my_out_len = mbedtls_x509_csr_info(my_out, sizeof(my_out), "", &csr);
+        TEST_ASSERT(my_out_len == strlen(ref_out));
+        TEST_ASSERT(strcmp(my_out, ref_out) == 0);
+    }
+
+exit:
+    mbedtls_x509_csr_free(&csr);
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
 void mbedtls_x509_crt_parse_path(char *crt_path, int ret, int nb_crt)
 {
@@ -1217,9 +1241,9 @@
 
     /* Load a chain with nb_int intermediates (from 01 to nb_int),
      * plus one "end-entity" cert (nb_int + 1) */
-    ret = mbedtls_snprintf(file_buf, sizeof file_buf, "%s/c%02d.pem", chain_dir,
+    ret = mbedtls_snprintf(file_buf, sizeof(file_buf), "%s/c%02d.pem", chain_dir,
                            nb_int + 1);
-    TEST_ASSERT(ret > 0 && (size_t) ret < sizeof file_buf);
+    TEST_ASSERT(ret > 0 && (size_t) ret < sizeof(file_buf));
     TEST_ASSERT(mbedtls_x509_crt_parse_file(&chain, file_buf) == 0);
 
     /* Try to verify that chain */
@@ -1312,13 +1336,13 @@
     mbedtls_x509_buf oid;
     char num_buf[100];
 
-    memset(num_buf, 0x2a, sizeof num_buf);
+    memset(num_buf, 0x2a, sizeof(num_buf));
 
     oid.tag = MBEDTLS_ASN1_OID;
     oid.p   = oid_buf->x;
     oid.len   = oid_buf->len;
 
-    TEST_ASSERT((size_t) blen <= sizeof num_buf);
+    TEST_ASSERT((size_t) blen <= sizeof(num_buf));
 
     TEST_ASSERT(mbedtls_oid_get_numeric_string(num_buf, blen, &oid) == ret);