Merge pull request #8212 from tom-cosgrove-arm/mbedtls_ssl_max_early_data_size-default-value

MBEDTLS_SSL_MAX_EARLY_DATA_SIZE: default value should be commented out in config
diff --git a/ChangeLog.d/extend-distinguished-names.txt b/ChangeLog.d/extend-distinguished-names.txt
new file mode 100644
index 0000000..b148424
--- /dev/null
+++ b/ChangeLog.d/extend-distinguished-names.txt
@@ -0,0 +1,3 @@
+Features
+   * Accept arbitrary AttributeType and AttributeValue in certificate
+     Distinguished Names using RFC 4514 syntax.
diff --git a/docs/driver-only-builds.md b/docs/driver-only-builds.md
index a55bbc5..4e2d68f 100644
--- a/docs/driver-only-builds.md
+++ b/docs/driver-only-builds.md
@@ -76,10 +76,6 @@
 Elliptic-curve cryptography (ECC)
 ---------------------------------
 
-Note: things are still evolving. This section describes the situation right
-after #7452 has been merged. It will be updated again in #7757 when bignum is
-done.
-
 It is possible to have most ECC operations provided only by a driver:
 - the ECDH, ECDSA and EC J-PAKE algorithms;
 - key import, export, and random generation.
@@ -107,6 +103,11 @@
 RSA or FFDH, then you can also disable `MBEDTLS_BIGNUM_C` for further code
 size saving.
 
+[Coming soon] As noted in the "Limitations regarding the selection of curves"
+section below, there is an upcoming requirement for all the required curves to
+also be accelerated in the PSA driver in order to exclude the builtin algs
+support.
+
 ### Limitations regarding fully removing `ecp.c`
 
 A limited subset of `ecp.c` will still be automatically re-enabled if any of
@@ -144,10 +145,34 @@
 
 ### Limitations regarding the selection of curves
 
-TODO: apparently we don't really support having some curves built-in and
-others driver-only... investigate and describe the situation. See also #7899.
+There is ongoing work which is trying to establish the links and constraints
+between the list of supported curves and supported algorithms both in the
+builtin and PSA sides. In particular:
+
+- #8014 ensures that the curves supported on the PSA side (`PSA_WANT_ECC_xxx`)
+  are always a superset of the builtin ones (`MBEDTLS_ECP_DP_xxx`)
+- #8016 forces builtin alg support as soon as there is at least one builtin
+  curve. In other words, in order to exclue all builtin algs, all the required
+  curves should be supported and accelerated by the PSA driver.
 
 Finite-field Diffie-Hellman
 ---------------------------
 
-TODO
+Support is pretty similar to the "Elliptic-curve cryptography (ECC)" section
+above.
+Key management and usage can be enabled by means of the usual `PSA_WANT` +
+`MBEDTLS_PSA_ACCEL` pairs:
+
+- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_PUBLIC_KEY`;
+- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_BASIC`;
+- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_IMPORT`;
+- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_EXPORT`;
+- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_GENERATE`;
+
+The same holds for the associated algorithm:
+`[PSA_WANT|MBEDTLS_PSA_ACCEL]_ALG_FFDH` allow builds accelerating FFDH and
+removing builtin support (i.e. `MBEDTLS_DHM_C`).
+
+### Limitations
+Support for deterministic derivation of a DH keypair
+(i.e. `PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_DERIVE`) is not supported.
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index 002c8de..c7aae0f 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -96,15 +96,14 @@
 
 /* Slightly smaller way to check if tag is a string tag
  * compared to canonical implementation. */
-#define MBEDTLS_ASN1_IS_STRING_TAG(tag)                                     \
-    ((tag) < 32u && (                                                      \
+#define MBEDTLS_ASN1_IS_STRING_TAG(tag)                                \
+    ((unsigned int) (tag) < 32u && (                                   \
          ((1u << (tag)) & ((1u << MBEDTLS_ASN1_BMP_STRING)       |     \
                            (1u << MBEDTLS_ASN1_UTF8_STRING)      |     \
                            (1u << MBEDTLS_ASN1_T61_STRING)       |     \
                            (1u << MBEDTLS_ASN1_IA5_STRING)       |     \
                            (1u << MBEDTLS_ASN1_UNIVERSAL_STRING) |     \
-                           (1u << MBEDTLS_ASN1_PRINTABLE_STRING) |     \
-                           (1u << MBEDTLS_ASN1_BIT_STRING))) != 0))
+                           (1u << MBEDTLS_ASN1_PRINTABLE_STRING))) != 0))
 
 /*
  * Bit masks for each of the components of an ASN.1 tag as specified in
@@ -210,6 +209,7 @@
 }
 mbedtls_asn1_named_data;
 
+#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C)
 /**
  * \brief       Get the length of an ASN.1 element.
  *              Updates the pointer to immediately behind the length.
@@ -256,7 +256,9 @@
 int mbedtls_asn1_get_tag(unsigned char **p,
                          const unsigned char *end,
                          size_t *len, int tag);
+#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */
 
+#if defined(MBEDTLS_ASN1_PARSE_C)
 /**
  * \brief       Retrieve a boolean ASN.1 tag and its value.
  *              Updates the pointer to immediately behind the full tag.
@@ -646,4 +648,6 @@
 }
 #endif
 
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
 #endif /* asn1.h */
diff --git a/include/mbedtls/asn1write.h b/include/mbedtls/asn1write.h
index 3c5072c..6fe57c8 100644
--- a/include/mbedtls/asn1write.h
+++ b/include/mbedtls/asn1write.h
@@ -48,6 +48,7 @@
 extern "C" {
 #endif
 
+#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C)
 /**
  * \brief           Write a length field in ASN.1 format.
  *
@@ -76,7 +77,9 @@
  */
 int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start,
                            unsigned char tag);
+#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */
 
+#if defined(MBEDTLS_ASN1_WRITE_C)
 /**
  * \brief           Write raw buffer data.
  *
@@ -393,4 +396,6 @@
 }
 #endif
 
+#endif /* MBEDTLS_ASN1_WRITE_C */
+
 #endif /* MBEDTLS_ASN1_WRITE_H */
diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h
index d37cc81..533e076 100644
--- a/include/mbedtls/build_info.h
+++ b/include/mbedtls/build_info.h
@@ -49,6 +49,31 @@
 #define MBEDTLS_VERSION_STRING         "3.4.1"
 #define MBEDTLS_VERSION_STRING_FULL    "Mbed TLS 3.4.1"
 
+/* Macros for build-time platform detection */
+
+#if !defined(MBEDTLS_ARCH_IS_ARM64) && \
+    (defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC))
+#define MBEDTLS_ARCH_IS_ARM64
+#endif
+
+#if !defined(MBEDTLS_ARCH_IS_ARM32) && \
+    (defined(__arm__) || defined(_M_ARM) || \
+    defined(_M_ARMT) || defined(__thumb__) || defined(__thumb2__))
+#define MBEDTLS_ARCH_IS_ARM32
+#endif
+
+#if !defined(MBEDTLS_ARCH_IS_X64) && \
+    (defined(__amd64__) || defined(__x86_64__) || \
+    ((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC)))
+#define MBEDTLS_ARCH_IS_X64
+#endif
+
+#if !defined(MBEDTLS_ARCH_IS_X86) && \
+    (defined(__i386__) || defined(_X86_) || \
+    (defined(_M_IX86) && !defined(_M_I86)))
+#define MBEDTLS_ARCH_IS_X86
+#endif
+
 #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
 #define _CRT_SECURE_NO_DEPRECATE 1
 #endif
diff --git a/library/aes.c b/library/aes.c
index 47a5e3e..0a7b26c 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -34,20 +34,19 @@
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
 
-#if defined(__aarch64__)
+#if defined(MBEDTLS_ARCH_IS_ARM64)
 #if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
 #error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
 #endif
 #endif
 
-#if defined(__amd64__) || defined(__x86_64__) || \
-    ((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC))
+#if defined(MBEDTLS_ARCH_IS_X64)
 #if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
 #error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
 #endif
 #endif
 
-#if defined(__i386__) || defined(_M_IX86)
+#if defined(MBEDTLS_ARCH_IS_X86)
 #if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
 #error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
 #endif
@@ -652,7 +651,7 @@
     }
 #endif
 
-#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
+#if defined(MBEDTLS_AESCE_HAVE_CODE)
     if (MBEDTLS_AESCE_HAS_SUPPORT()) {
         return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
     }
@@ -764,7 +763,7 @@
     }
 #endif
 
-#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
+#if defined(MBEDTLS_AESCE_HAVE_CODE)
     if (MBEDTLS_AESCE_HAS_SUPPORT()) {
         mbedtls_aesce_inverse_key(
             (unsigned char *) RK,
@@ -1091,7 +1090,7 @@
     }
 #endif
 
-#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
+#if defined(MBEDTLS_AESCE_HAVE_CODE)
     if (MBEDTLS_AESCE_HAS_SUPPORT()) {
         return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
     }
@@ -1910,7 +1909,7 @@
             mbedtls_printf("  AES note: using VIA Padlock.\n");
         } else
 #endif
-#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
+#if defined(MBEDTLS_AESCE_HAVE_CODE)
         if (MBEDTLS_AESCE_HAS_SUPPORT()) {
             mbedtls_printf("  AES note: using AESCE.\n");
         } else
diff --git a/library/aesce.c b/library/aesce.c
index 6f75a67..8b42b03 100644
--- a/library/aesce.c
+++ b/library/aesce.c
@@ -46,7 +46,7 @@
 
 #include "aesce.h"
 
-#if defined(MBEDTLS_HAVE_ARM64)
+#if defined(MBEDTLS_ARCH_IS_ARM64)
 
 /* Compiler version checks. */
 #if defined(__clang__)
@@ -510,6 +510,6 @@
 #undef MBEDTLS_POP_TARGET_PRAGMA
 #endif
 
-#endif /* MBEDTLS_HAVE_ARM64 */
+#endif /* MBEDTLS_ARCH_IS_ARM64 */
 
 #endif /* MBEDTLS_AESCE_C */
diff --git a/library/aesce.h b/library/aesce.h
index 735c8cf..d24c423 100644
--- a/library/aesce.h
+++ b/library/aesce.h
@@ -30,13 +30,10 @@
 
 #include "mbedtls/aes.h"
 
-#if !defined(MBEDTLS_HAVE_ARM64)
-#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
-#define MBEDTLS_HAVE_ARM64
-#endif
-#endif
 
-#if defined(MBEDTLS_HAVE_ARM64)
+#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_ARCH_IS_ARM64)
+
+#define MBEDTLS_AESCE_HAVE_CODE
 
 #ifdef __cplusplus
 extern "C" {
@@ -131,6 +128,6 @@
 }
 #endif
 
-#endif /* MBEDTLS_HAVE_ARM64 */
+#endif /* MBEDTLS_AESCE_C && MBEDTLS_ARCH_IS_ARM64 */
 
 #endif /* MBEDTLS_AESCE_H */
diff --git a/library/aesni.h b/library/aesni.h
index 332a0f0..ba14290 100644
--- a/library/aesni.h
+++ b/library/aesni.h
@@ -32,23 +32,8 @@
 #define MBEDTLS_AESNI_AES      0x02000000u
 #define MBEDTLS_AESNI_CLMUL    0x00000002u
 
-/* Can we do AESNI with inline assembly?
- * (Only implemented with gas syntax, only for 64-bit.)
- */
-#if !defined(MBEDTLS_HAVE_X86_64) && \
-    (defined(__amd64__) || defined(__x86_64__) || \
-    defined(_M_X64) || defined(_M_AMD64)) && \
-    !defined(_M_ARM64EC)
-#define MBEDTLS_HAVE_X86_64
-#endif
-
-#if !defined(MBEDTLS_HAVE_X86) && \
-    (defined(__i386__) || defined(_M_IX86))
-#define MBEDTLS_HAVE_X86
-#endif
-
 #if defined(MBEDTLS_AESNI_C) && \
-    (defined(MBEDTLS_HAVE_X86_64) || defined(MBEDTLS_HAVE_X86))
+    (defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_X86))
 
 /* Can we do AESNI with intrinsics?
  * (Only implemented with certain compilers, only for certain targets.)
@@ -75,7 +60,10 @@
 #if defined(MBEDTLS_AESNI_HAVE_INTRINSICS)
 #define MBEDTLS_AESNI_HAVE_CODE 2 // via intrinsics
 #elif defined(MBEDTLS_HAVE_ASM) && \
-    defined(__GNUC__) && defined(MBEDTLS_HAVE_X86_64)
+    defined(__GNUC__) && defined(MBEDTLS_ARCH_IS_X64)
+/* Can we do AESNI with inline assembly?
+ * (Only implemented with gas syntax, only for 64-bit.)
+ */
 #define MBEDTLS_AESNI_HAVE_CODE 1 // via assembly
 #elif defined(__GNUC__)
 #   error "Must use `-mpclmul -msse2 -maes` for MBEDTLS_AESNI_C"
diff --git a/library/asn1parse.c b/library/asn1parse.c
index d257ef4..edc4c69 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -19,7 +19,7 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_ASN1_PARSE_C)
+#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C)
 
 #include "mbedtls/asn1.h"
 #include "mbedtls/platform_util.h"
@@ -114,7 +114,9 @@
 
     return mbedtls_asn1_get_len(p, end, len);
 }
+#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */
 
+#if defined(MBEDTLS_ASN1_PARSE_C)
 int mbedtls_asn1_get_bool(unsigned char **p,
                           const unsigned char *end,
                           int *val)
diff --git a/library/asn1write.c b/library/asn1write.c
index c65d937..4123ac3 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -19,7 +19,7 @@
 
 #include "common.h"
 
-#if defined(MBEDTLS_ASN1_WRITE_C)
+#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C)
 
 #include "mbedtls/asn1write.h"
 #include "mbedtls/error.h"
@@ -102,7 +102,9 @@
 
     return 1;
 }
+#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */
 
+#if defined(MBEDTLS_ASN1_WRITE_C)
 int mbedtls_asn1_write_raw_buffer(unsigned char **p, const unsigned char *start,
                                   const unsigned char *buf, size_t size)
 {
diff --git a/library/gcm.c b/library/gcm.c
index 786290f..b06ca4a 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -97,7 +97,7 @@
     }
 #endif
 
-#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
+#if defined(MBEDTLS_AESCE_HAVE_CODE)
     if (MBEDTLS_AESCE_HAS_SUPPORT()) {
         return 0;
     }
@@ -208,7 +208,7 @@
     }
 #endif /* MBEDTLS_AESNI_HAVE_CODE */
 
-#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
+#if defined(MBEDTLS_AESCE_HAVE_CODE)
     if (MBEDTLS_AESCE_HAS_SUPPORT()) {
         unsigned char h[16];
 
@@ -885,7 +885,7 @@
         } else
 #endif
 
-#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
+#if defined(MBEDTLS_AESCE_HAVE_CODE)
         if (MBEDTLS_AESCE_HAS_SUPPORT()) {
             mbedtls_printf("  GCM note: using AESCE.\n");
         } else
diff --git a/library/padlock.c b/library/padlock.c
index f42c40f..563d40e 100644
--- a/library/padlock.c
+++ b/library/padlock.c
@@ -31,7 +31,7 @@
 
 #include <string.h>
 
-#if defined(MBEDTLS_HAVE_X86)
+#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
 
 /*
  * PadLock detection routine
@@ -162,6 +162,6 @@
     return 0;
 }
 
-#endif /* MBEDTLS_HAVE_X86 */
+#endif /* MBEDTLS_VIA_PADLOCK_HAVE_CODE */
 
 #endif /* MBEDTLS_PADLOCK_C */
diff --git a/library/padlock.h b/library/padlock.h
index ae5c486..a00afe0 100644
--- a/library/padlock.h
+++ b/library/padlock.h
@@ -38,16 +38,17 @@
 #endif
 #endif
 
-/* Some versions of ASan result in errors about not enough registers */
-#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) && \
+/*
+ * - `padlock` is implements with GNUC assembly for x86 target.
+ * - Some versions of ASan result in errors about not enough registers.
+ */
+#if defined(MBEDTLS_PADLOCK_C) && \
+    defined(__GNUC__) && defined(MBEDTLS_ARCH_IS_X86) && \
+    defined(MBEDTLS_HAVE_ASM) && \
     !defined(MBEDTLS_HAVE_ASAN)
 
 #define MBEDTLS_VIA_PADLOCK_HAVE_CODE
 
-#ifndef MBEDTLS_HAVE_X86
-#define MBEDTLS_HAVE_X86
-#endif
-
 #include <stdint.h>
 
 #define MBEDTLS_PADLOCK_RNG 0x000C
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 456d4e3..15a6984 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -4174,7 +4174,7 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE];
-    size_t default_iv_length;
+    size_t default_iv_length = 0;
 
     if (operation->id == 0) {
         status = PSA_ERROR_BAD_STATE;
@@ -4784,7 +4784,7 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     uint8_t local_nonce[PSA_AEAD_NONCE_MAX_SIZE];
-    size_t required_nonce_size;
+    size_t required_nonce_size = 0;
 
     *nonce_length = 0;
 
diff --git a/library/ssl_cache.c b/library/ssl_cache.c
index 1c285ec..929c28b 100644
--- a/library/ssl_cache.c
+++ b/library/ssl_cache.c
@@ -264,7 +264,7 @@
     mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
     mbedtls_ssl_cache_entry *cur;
 
-    size_t session_serialized_len;
+    size_t session_serialized_len = 0;
     unsigned char *session_serialized = NULL;
 
 #if defined(MBEDTLS_THREADING_C)
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 7114ef0..2ff39f4 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -648,14 +648,16 @@
           MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
 
 #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
-    if (
+    int write_sig_alg_ext = 0;
 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
-        (propose_tls13 && mbedtls_ssl_conf_tls13_ephemeral_enabled(ssl)) ||
+    write_sig_alg_ext = write_sig_alg_ext ||
+                        (propose_tls13 && mbedtls_ssl_conf_tls13_ephemeral_enabled(ssl));
 #endif
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-        propose_tls12 ||
+    write_sig_alg_ext = write_sig_alg_ext || propose_tls12;
 #endif
-        0) {
+
+    if (write_sig_alg_ext) {
         ret = mbedtls_ssl_write_sig_alg_ext(ssl, p, end, &output_len);
         if (ret != 0) {
             return ret;
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index 85632a1..47a206d 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -1504,7 +1504,8 @@
 
     int auth_done = 0;
 #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
-    size_t padlen = 0, correct = 1;
+    size_t padlen = 0;
+    mbedtls_ct_condition_t correct = MBEDTLS_CT_TRUE;
 #endif
     unsigned char *data;
     /* For an explanation of the additional data length see
@@ -1921,7 +1922,7 @@
             const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge(
                 rec->data_len,
                 padlen + 1);
-            correct = mbedtls_ct_size_if_else_0(ge, correct);
+            correct = mbedtls_ct_bool_and(ge, correct);
             padlen  = mbedtls_ct_size_if_else_0(ge, padlen);
         } else {
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
@@ -1937,7 +1938,7 @@
             const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge(
                 rec->data_len,
                 transform->maclen + padlen + 1);
-            correct = mbedtls_ct_size_if_else_0(ge, correct);
+            correct = mbedtls_ct_bool_and(ge, correct);
             padlen  = mbedtls_ct_size_if_else_0(ge, padlen);
         }
 
@@ -1973,14 +1974,14 @@
             increment = mbedtls_ct_size_if_else_0(b, increment);
             pad_count += increment;
         }
-        correct = mbedtls_ct_size_if_else_0(mbedtls_ct_uint_eq(pad_count, padlen), correct);
+        correct = mbedtls_ct_bool_and(mbedtls_ct_uint_eq(pad_count, padlen), correct);
 
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
-        if (padlen > 0 && correct == 0) {
+        if (padlen > 0 && correct == MBEDTLS_CT_FALSE) {
             MBEDTLS_SSL_DEBUG_MSG(1, ("bad padding byte detected"));
         }
 #endif
-        padlen = mbedtls_ct_size_if_else_0(mbedtls_ct_bool(correct), padlen);
+        padlen = mbedtls_ct_size_if_else_0(correct, padlen);
 
 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
 
@@ -2075,7 +2076,7 @@
 #if defined(MBEDTLS_SSL_DEBUG_ALL)
             MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match"));
 #endif
-            correct = 0;
+            correct = MBEDTLS_CT_FALSE;
         }
         auth_done++;
 
@@ -2090,7 +2091,7 @@
     /*
      * Finally check the correct flag
      */
-    if (correct == 0) {
+    if (correct == MBEDTLS_CT_FALSE) {
         return MBEDTLS_ERR_SSL_INVALID_MAC;
     }
 #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 7a1f855..64a3878 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4578,13 +4578,14 @@
      * We can't check that the config matches the initial one, but we can at
      * least check it matches the requirements for serializing.
      */
-    if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
-        ssl->conf->max_tls_version < MBEDTLS_SSL_VERSION_TLS1_2 ||
-        ssl->conf->min_tls_version > MBEDTLS_SSL_VERSION_TLS1_2 ||
+    if (
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
         ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
 #endif
-        0) {
+        ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+        ssl->conf->max_tls_version < MBEDTLS_SSL_VERSION_TLS1_2 ||
+        ssl->conf->min_tls_version > MBEDTLS_SSL_VERSION_TLS1_2
+        ) {
         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
     }
 
diff --git a/library/x509.c b/library/x509.c
index ee7a2b2..990393c 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -43,6 +43,8 @@
 #include "mbedtls/pem.h"
 #endif
 
+#include "mbedtls/asn1write.h"
+
 #include "mbedtls/platform.h"
 
 #if defined(MBEDTLS_HAVE_TIME)
@@ -810,6 +812,11 @@
     return 0;
 }
 
+static char nibble_to_hex_digit(int i)
+{
+    return (i < 10) ? (i + '0') : (i - 10 + 'A');
+}
+
 /*
  * Store the name in printable form into buf; no more
  * than size characters will be written
@@ -817,11 +824,16 @@
 int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
 {
     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t i, j, n;
+    size_t i, j, n, asn1_len_size, asn1_tag_size, asn1_tag_len_buf_start;
+    /* 6 is enough as our asn1 write functions only write one byte for the tag and at most five bytes for the length*/
+    unsigned char asn1_tag_len_buf[6];
+    unsigned char *asn1_len_p;
     unsigned char c, merge = 0;
     const mbedtls_x509_name *name;
     const char *short_name = NULL;
+    char lowbits, highbits;
     char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
+    int print_hexstring;
 
     memset(s, 0, sizeof(s));
 
@@ -840,32 +852,91 @@
             MBEDTLS_X509_SAFE_SNPRINTF;
         }
 
-        ret = mbedtls_oid_get_attr_short_name(&name->oid, &short_name);
+        print_hexstring = (name->val.tag != MBEDTLS_ASN1_UTF8_STRING) &&
+                          (name->val.tag != MBEDTLS_ASN1_PRINTABLE_STRING) &&
+                          (name->val.tag != MBEDTLS_ASN1_IA5_STRING);
 
-        if (ret == 0) {
+        if ((ret = mbedtls_oid_get_attr_short_name(&name->oid, &short_name)) == 0) {
             ret = mbedtls_snprintf(p, n, "%s=", short_name);
         } else {
-            ret = mbedtls_snprintf(p, n, "\?\?=");
+            if ((ret = mbedtls_oid_get_numeric_string(p, n, &name->oid)) > 0) {
+                n -= ret;
+                p += ret;
+                ret = mbedtls_snprintf(p, n, "=");
+                print_hexstring = 1;
+            } else if (ret == MBEDTLS_ERR_OID_BUF_TOO_SMALL) {
+                return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
+            } else {
+                ret = mbedtls_snprintf(p, n, "\?\?=");
+            }
         }
         MBEDTLS_X509_SAFE_SNPRINTF;
 
-        for (i = 0, j = 0; i < name->val.len; i++, j++) {
-            if (j >= sizeof(s) - 1) {
-                return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
-            }
+        if (print_hexstring) {
+            s[0] = '#';
 
-            c = name->val.p[i];
-            // Special characters requiring escaping, RFC 1779
-            if (c && strchr(",=+<>#;\"\\", c)) {
+            asn1_len_p = asn1_tag_len_buf + sizeof(asn1_tag_len_buf);
+            if ((ret = mbedtls_asn1_write_len(&asn1_len_p, asn1_tag_len_buf, name->val.len)) < 0) {
+                return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+            }
+            asn1_len_size = ret;
+            if ((ret = mbedtls_asn1_write_tag(&asn1_len_p, asn1_tag_len_buf, name->val.tag)) < 0) {
+                return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+            }
+            asn1_tag_size = ret;
+            asn1_tag_len_buf_start = sizeof(asn1_tag_len_buf) - asn1_len_size - asn1_tag_size;
+            for (i = 0, j = 1; i < asn1_len_size + asn1_tag_size; i++) {
                 if (j + 1 >= sizeof(s) - 1) {
                     return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
                 }
-                s[j++] = '\\';
+                c = asn1_tag_len_buf[asn1_tag_len_buf_start+i];
+                lowbits = (c & 0x0F);
+                highbits = c >> 4;
+                s[j++] = nibble_to_hex_digit(highbits);
+                s[j++] = nibble_to_hex_digit(lowbits);
             }
-            if (c < 32 || c >= 127) {
-                s[j] = '?';
-            } else {
-                s[j] = c;
+            for (i = 0; i < name->val.len; i++) {
+                if (j + 1 >= sizeof(s) - 1) {
+                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
+                }
+                c = name->val.p[i];
+                lowbits = (c & 0x0F);
+                highbits = c >> 4;
+                s[j++] = nibble_to_hex_digit(highbits);
+                s[j++] = nibble_to_hex_digit(lowbits);
+            }
+        } else {
+            for (i = 0, j = 0; i < name->val.len; i++, j++) {
+                if (j >= sizeof(s) - 1) {
+                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
+                }
+
+                c = name->val.p[i];
+                // Special characters requiring escaping, RFC 4514 Section 2.4
+                if (c == '\0') {
+                    return MBEDTLS_ERR_X509_INVALID_NAME;
+                } else {
+                    if (strchr(",=+<>;\"\\", c) ||
+                        ((i == 0) && strchr("# ", c)) ||
+                        ((i == name->val.len-1) && (c == ' '))) {
+                        if (j + 1 >= sizeof(s) - 1) {
+                            return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
+                        }
+                        s[j++] = '\\';
+                    }
+                }
+                if (c < 32 || c >= 127) {
+                    if (j + 3 >= sizeof(s) - 1) {
+                        return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
+                    }
+                    s[j++] = '\\';
+                    lowbits = (c & 0x0F);
+                    highbits = c >> 4;
+                    s[j++] = nibble_to_hex_digit(highbits);
+                    s[j] = nibble_to_hex_digit(lowbits);
+                } else {
+                    s[j] = c;
+                }
             }
         }
         s[j] = '\0';
diff --git a/library/x509_create.c b/library/x509_create.c
index bd772d3..1c489a3 100644
--- a/library/x509_create.c
+++ b/library/x509_create.c
@@ -28,6 +28,10 @@
 
 #include <string.h>
 
+#include "mbedtls/platform.h"
+
+#include "mbedtls/asn1.h"
+
 /* Structure linking OIDs for X.509 DN AttributeTypes to their
  * string representations and default string encodings used by Mbed TLS. */
 typedef struct {
@@ -35,7 +39,8 @@
                        * "CN" or "emailAddress". */
     size_t name_len; /* Length of 'name', without trailing 0 byte. */
     const char *oid; /* String representation of OID of AttributeType,
-                      * as per RFC 5280, Appendix A.1. */
+                      * as per RFC 5280, Appendix A.1. encoded as per
+                      * X.690 */
     int default_tag; /* The default character encoding used for the
                       * given attribute type, e.g.
                       * MBEDTLS_ASN1_UTF8_STRING for UTF-8. */
@@ -123,79 +128,200 @@
     return cur;
 }
 
+static int hex_to_int(char c)
+{
+    return ('0' <= c && c <= '9') ? (c - '0') :
+           ('a' <= c && c <= 'f') ? (c - 'a' + 10) :
+           ('A' <= c && c <= 'F') ? (c - 'A' + 10) : -1;
+}
+
+static int hexpair_to_int(const char *hexpair)
+{
+    int n1 = hex_to_int(*hexpair);
+    int n2 = hex_to_int(*(hexpair + 1));
+
+    if (n1 != -1 && n2 != -1) {
+        return (n1 << 4) | n2;
+    } else {
+        return -1;
+    }
+}
+
+static int parse_attribute_value_string(const char *s,
+                                        int len,
+                                        unsigned char *data,
+                                        size_t *data_len)
+{
+    const char *c;
+    const char *end = s + len;
+    unsigned char *d = data;
+    int n;
+
+    for (c = s; c < end; c++) {
+        if (*c == '\\') {
+            c++;
+
+            /* Check for valid escaped characters as per RFC 4514 Section 3 */
+            if (c + 1 < end && (n = hexpair_to_int(c)) != -1) {
+                if (n == 0) {
+                    return MBEDTLS_ERR_X509_INVALID_NAME;
+                }
+                *(d++) = n;
+                c++;
+            } else if (c < end && strchr(" ,=+<>#;\"\\", *c)) {
+                *(d++) = *c;
+            } else {
+                return MBEDTLS_ERR_X509_INVALID_NAME;
+            }
+        } else {
+            *(d++) = *c;
+        }
+
+        if (d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE) {
+            return MBEDTLS_ERR_X509_INVALID_NAME;
+        }
+    }
+    *data_len = d - data;
+    return 0;
+}
+
+static int parse_attribute_value_der_encoded(const char *s,
+                                             int len,
+                                             unsigned char *data,
+                                             size_t *data_len,
+                                             int *tag)
+{
+    const char *c = s;
+    const char *end = c + len;
+    unsigned char asn1_der_buf[MBEDTLS_X509_MAX_DN_NAME_SIZE];
+    unsigned char *asn1_der_end;
+    unsigned char *p;
+    unsigned char *d = data;
+    int n;
+
+    /* Converting from hexstring to raw binary so we can use asn1parse.c */
+    if ((len < 5) || (*c != '#')) {
+        return MBEDTLS_ERR_X509_INVALID_NAME;
+    }
+    c++;
+    if ((*tag = hexpair_to_int(c)) == -1) {
+        return MBEDTLS_ERR_X509_INVALID_NAME;
+    }
+    c += 2;
+    p = asn1_der_buf;
+    for (p = asn1_der_buf; c < end; c += 2) {
+        if ((c + 1 >= end) || (n = hexpair_to_int(c)) == -1) {
+            return MBEDTLS_ERR_X509_INVALID_NAME;
+        }
+        if (MBEDTLS_ASN1_IS_STRING_TAG(*tag) && n == 0) {
+            return MBEDTLS_ERR_X509_INVALID_NAME;
+        }
+        *(p++) = n;
+    }
+    asn1_der_end = p;
+
+    p = asn1_der_buf;
+    if (mbedtls_asn1_get_len(&p, asn1_der_end, data_len) != 0) {
+        return MBEDTLS_ERR_X509_INVALID_NAME;
+    }
+
+    while (p < asn1_der_end) {
+        *(d++) = *(p++);
+    }
+
+    return 0;
+}
+
 int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name)
 {
     int ret = MBEDTLS_ERR_X509_INVALID_NAME;
+    int parse_ret = 0;
     const char *s = name, *c = s;
     const char *end = s + strlen(s);
-    const char *oid = NULL;
+    mbedtls_asn1_buf oid = { .p = NULL, .len = 0, .tag = MBEDTLS_ASN1_NULL };
     const x509_attr_descriptor_t *attr_descr = NULL;
-    int in_tag = 1;
-    char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
-    char *d = data;
+    int in_attr_type = 1;
+    int tag;
+    int numericoid = 0;
+    unsigned char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
+    size_t data_len = 0;
 
     /* Clear existing chain if present */
     mbedtls_asn1_free_named_data_list(head);
 
     while (c <= end) {
-        if (in_tag && *c == '=') {
+        if (in_attr_type && *c == '=') {
             if ((attr_descr = x509_attr_descr_from_name(s, c - s)) == NULL) {
-                ret = MBEDTLS_ERR_X509_UNKNOWN_OID;
-                goto exit;
+                if ((mbedtls_oid_from_numeric_string(&oid, s, c - s)) != 0) {
+                    return MBEDTLS_ERR_X509_INVALID_NAME;
+                } else {
+                    numericoid = 1;
+                }
+            } else {
+                oid.len = strlen(attr_descr->oid);
+                oid.p = mbedtls_calloc(1, oid.len);
+                memcpy(oid.p, attr_descr->oid, oid.len);
+                numericoid = 0;
             }
 
-            oid = attr_descr->oid;
             s = c + 1;
-            in_tag = 0;
-            d = data;
+            in_attr_type = 0;
         }
 
-        if (!in_tag && *c == '\\' && c != end) {
-            c++;
-
-            /* Check for valid escaped characters */
-            if (c == end || *c != ',') {
-                ret = MBEDTLS_ERR_X509_INVALID_NAME;
-                goto exit;
+        if (!in_attr_type && ((*c == ',' && *(c-1) != '\\') || c == end)) {
+            if (s == c) {
+                mbedtls_free(oid.p);
+                return MBEDTLS_ERR_X509_INVALID_NAME;
+            } else if (*s == '#') {
+                if ((parse_ret =
+                         parse_attribute_value_der_encoded(s, (int) (c - s), data, &data_len,
+                                                           &tag)) != 0) {
+                    mbedtls_free(oid.p);
+                    return MBEDTLS_ERR_X509_INVALID_NAME;
+                }
+            } else {
+                if (numericoid) {
+                    mbedtls_free(oid.p);
+                    return MBEDTLS_ERR_X509_INVALID_NAME;
+                } else {
+                    if ((parse_ret =
+                             parse_attribute_value_string(s, (int) (c - s), data,
+                                                          &data_len)) != 0) {
+                        mbedtls_free(oid.p);
+                        return parse_ret;
+                    }
+                    tag = attr_descr->default_tag;
+                }
             }
-        } else if (!in_tag && (*c == ',' || c == end)) {
-            mbedtls_asn1_named_data *cur =
-                mbedtls_asn1_store_named_data(head, oid, strlen(oid),
-                                              (unsigned char *) data,
-                                              d - data);
 
+            mbedtls_asn1_named_data *cur =
+                mbedtls_asn1_store_named_data(head, (char *) oid.p, oid.len,
+                                              (unsigned char *) data,
+                                              data_len);
+            mbedtls_free(oid.p);
+            oid.p = NULL;
             if (cur == NULL) {
                 return MBEDTLS_ERR_X509_ALLOC_FAILED;
             }
 
             // set tagType
-            cur->val.tag = attr_descr->default_tag;
+            cur->val.tag = tag;
 
             while (c < end && *(c + 1) == ' ') {
                 c++;
             }
 
             s = c + 1;
-            in_tag = 1;
+            in_attr_type = 1;
 
             /* Successfully parsed one name, update ret to success */
             ret = 0;
         }
-
-        if (!in_tag && s != c + 1) {
-            *(d++) = *c;
-
-            if (d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE) {
-                ret = MBEDTLS_ERR_X509_INVALID_NAME;
-                goto exit;
-            }
-        }
-
         c++;
     }
-
-exit:
-
+    if (oid.p != NULL) {
+        mbedtls_free(oid.p);
+    }
     return ret;
 }
 
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index f50f058..21ca489 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -1441,6 +1441,14 @@
 parse_input/server1.req.commas.sha256: server1.key
 	$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O=PolarSSL\, Commas,CN=PolarSSL Server 1" md=SHA256
 
+parse_input/server1.req.hashsymbol.sha256: server1.key
+	$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O=\#PolarSSL,CN=PolarSSL Server 1" md=SHA256
+
+parse_input/server1.req.spaces.sha256: server1.key
+	$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O= PolarSSL ,CN=PolarSSL Server 1" md=SHA256
+
+parse_input/server1.req.asciichars.sha256: server1.key
+	$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< subject_name="C=NL,O=极地SSL,CN=PolarSSL Server 1" md=SHA256
 # server2*
 
 server2_pwd_ec = PolarSSLTest
@@ -1590,7 +1598,13 @@
 	$(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@
 server1.commas.crt: server1.key parse_input/server1.req.commas.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
 	$(MBEDTLS_CERT_WRITE) request_file=parse_input/server1.req.commas.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 version=3 output_file=$@
-all_final += server1.crt server1.noauthid.crt parse_input/server1.crt.der server1.commas.crt
+server1.hashsymbol.crt: server1.key parse_input/server1.req.hashsymbol.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
+	$(MBEDTLS_CERT_WRITE) request_file=parse_input/server1.req.hashsymbol.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 version=3 output_file=$@
+server1.spaces.crt: server1.key parse_input/server1.req.spaces.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
+	$(MBEDTLS_CERT_WRITE) request_file=parse_input/server1.req.spaces.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 version=3 output_file=$@
+server1.asciichars.crt: server1.key parse_input/server1.req.asciichars.sha256 $(test_ca_crt) $(test_ca_key_file_rsa)
+	$(MBEDTLS_CERT_WRITE) request_file=parse_input/server1.req.asciichars.sha256 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20190210144406 not_after=20290210144406 md=SHA1 version=3 output_file=$@
+all_final += server1.crt server1.noauthid.crt parse_input/server1.crt.der server1.commas.crt server1.hashsymbol.crt server1.spaces.crt server1.asciichars.crt
 
 parse_input/server1.key_usage.crt: parse_input/server1.req.sha256
 server1.key_usage.crt: server1.req.sha256
diff --git a/tests/data_files/server1.asciichars.crt b/tests/data_files/server1.asciichars.crt
new file mode 100644
index 0000000..824e46e
--- /dev/null
+++ b/tests/data_files/server1.asciichars.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDQDCCAiigAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA9MQswCQYDVQQGEwJOTDESMBAG
+A1UECgwJ5p6B5ZywU1NMMRowGAYDVQQDDBFQb2xhclNTTCBTZXJ2ZXIgMTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkCHz1AatVVU4v9Nu6CZS4VYV6J
+v7joRZDb7ogWUtPxQ1BHlhJZZIdr/SvgRvlzvt3PkuGRW+1moG+JKXlFgNCDatVB
+Q3dfOXwJBEeCsFc5cO2j7BUZHqgzCEfBBUKp/UzDtN/dBh9NEFFAZ3MTD0D4bYEl
+XwqxU8YwfhU5rPla7n+SnqYFW+cTl4W1I5LZ1CQG1QkliXUH3aYajz8JGb6tZSxk
+65Wb3P5BXhem2mxbacwCuhQsFiScStzN0PdSZ3PxLaAj/X70McotcMqJCwTbLqZP
+cG6ezr1YieJTWZ5uWpJl4og/DJQZo93l6J2VE+0p26twEtxaymsXq1KCVLECAwEA
+AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUH3TWPynBdHRFOwUSLD2ovUNZAqYw
+HwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQAD
+ggEBAHqJLYmgkQ6yqml3PZM6iwbmo+lZLyDEPFpl/thHZm5LI8TTYOeU+wMAZ6KI
+VumyjZxypmLF2MiiJ2f3zQooU7H1waAcTpsafTuD6RRYdthYYxs1L9gCm1ZT2Ga8
+fgn3wrugPLUrtSM/TkTj6F4XkSlluzZpEKsSYLSoyde+uQgdbtR+3Tc+3oU8xBMM
+N6uq4VQC49avIQkI+598E3vKrjGGt3l2a1Ts1qvXWjo9mpJW5GM4e1zfogKnc8XQ
+K1hYQ39wL42l9Hijwre85O0PSBfbNOv1BPSDm8das3VNzGsUIz8InkAKAKCKwxG6
+BCw3D/CE8s6DCnpb+eK1sVJwZ4E=
+-----END CERTIFICATE-----
diff --git a/tests/data_files/server1.hashsymbol.crt b/tests/data_files/server1.hashsymbol.crt
new file mode 100644
index 0000000..9db7300
--- /dev/null
+++ b/tests/data_files/server1.hashsymbol.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDQDCCAiigAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA9MQswCQYDVQQGEwJOTDESMBAG
+A1UECgwJI1BvbGFyU1NMMRowGAYDVQQDDBFQb2xhclNTTCBTZXJ2ZXIgMTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkCHz1AatVVU4v9Nu6CZS4VYV6J
+v7joRZDb7ogWUtPxQ1BHlhJZZIdr/SvgRvlzvt3PkuGRW+1moG+JKXlFgNCDatVB
+Q3dfOXwJBEeCsFc5cO2j7BUZHqgzCEfBBUKp/UzDtN/dBh9NEFFAZ3MTD0D4bYEl
+XwqxU8YwfhU5rPla7n+SnqYFW+cTl4W1I5LZ1CQG1QkliXUH3aYajz8JGb6tZSxk
+65Wb3P5BXhem2mxbacwCuhQsFiScStzN0PdSZ3PxLaAj/X70McotcMqJCwTbLqZP
+cG6ezr1YieJTWZ5uWpJl4og/DJQZo93l6J2VE+0p26twEtxaymsXq1KCVLECAwEA
+AaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUH3TWPynBdHRFOwUSLD2ovUNZAqYw
+HwYDVR0jBBgwFoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQAD
+ggEBAJcKcv/Xro61Sxm0GH42pYu7AvtD2b8nynvA8BW9gCHmiIHvHQWNO9NTMuno
+1+HdzQVF1JxHC/A/hvXsczxGEc3jVnVeg1fwi8mZ/Fy1XtAVCTA0yJu7JTaaYbg+
+IU2y7Nu36FSOztLpOfHGmwVDoJ1+wCzG/id64hXwJRrHvUfGK4EvIsV97swhk2Do
+zSAfDA9N+QNV4zeiF9mLMOpUhCUBq8r41EDqm9lM0wSd3HNen8jwO20F4F1b1dYm
+L+bMarvUgHq91f128m2fF3sWNnz4RGoagSI/aOU/AP6Ksq8SUruGHpqrVWLClA6n
+EyyTPlNTwYIRCydZt7zlsw1/4h4=
+-----END CERTIFICATE-----
diff --git a/tests/data_files/server1.spaces.crt b/tests/data_files/server1.spaces.crt
new file mode 100644
index 0000000..b77132a
--- /dev/null
+++ b/tests/data_files/server1.spaces.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDQTCCAimgAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER
+MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
+MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA+MQswCQYDVQQGEwJOTDETMBEG
+A1UECgwKIFBvbGFyU1NMIDEaMBgGA1UEAwwRUG9sYXJTU0wgU2VydmVyIDEwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpAh89QGrVVVOL/TbugmUuFWFe
+ib+46EWQ2+6IFlLT8UNQR5YSWWSHa/0r4Eb5c77dz5LhkVvtZqBviSl5RYDQg2rV
+QUN3Xzl8CQRHgrBXOXDto+wVGR6oMwhHwQVCqf1Mw7Tf3QYfTRBRQGdzEw9A+G2B
+JV8KsVPGMH4VOaz5Wu5/kp6mBVvnE5eFtSOS2dQkBtUJJYl1B92mGo8/CRm+rWUs
+ZOuVm9z+QV4XptpsW2nMAroULBYknErczdD3Umdz8S2gI/1+9DHKLXDKiQsE2y6m
+T3Buns69WIniU1meblqSZeKIPwyUGaPd5eidlRPtKdurcBLcWsprF6tSglSxAgMB
+AAGjTTBLMAkGA1UdEwQCMAAwHQYDVR0OBBYEFB901j8pwXR0RTsFEiw9qL1DWQKm
+MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBBQUA
+A4IBAQBsR3jOFh7uGF5MCvEK8DrSmmvcFJzMmTRp0hCMeb0wEULhrMKeRDIa2yvr
+FrHHCUNAk2HjsjJevpCM8f3ibDqecckfbxE2vT9IUCmPrtOWmhQR/Il5TR9FvYns
+4BF1KUPRqGUFAXoIN+xKcYdp+myIluGHumM4Bop7tAZ5gg68IV/UJh5RqShxiLgV
+rxHzrp6oM1kn199m2wc1Twy2YwcNmfJDSOLV6K4xWjwcc8Eq+rLhuWUs5GNdrSEY
+ZjWmF1AlbVVChU3Dl5XOAY8T6+wJst5RIwkf1Fl1TPCZX8FWzGM9HYiYW0cC7cno
+IdSS7mVGxNrNe+6/Cu+zfqeiLdN2
+-----END CERTIFICATE-----
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index ffac222..068c000 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -2662,16 +2662,29 @@
     tests/ssl-opt.sh
 }
 
-# This function is really similar to config_psa_crypto_no_ecp_at_all() above so
-# its description is basically the same. The main difference in this case is
-# that when the EC built-in implementation is disabled, then also Bignum module
-# and its dependencies are disabled as well.
-#
-# This is the common helper between:
+# This is a common configuration helper used directly from:
+# - common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum
+# - common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum
+# and indirectly from:
 # - component_test_psa_crypto_config_accel_ecc_no_bignum
+#       - accelerate all EC algs, disable RSA and FFDH
 # - component_test_psa_crypto_config_reference_ecc_no_bignum
-config_psa_crypto_config_accel_ecc_no_bignum() {
+#       - this is the reference component of the above
+#       - it still disables RSA and FFDH, but it uses builtin EC algs
+# - component_test_psa_crypto_config_accel_ecc_ffdh_no_bignum
+#       - accelerate all EC and FFDH algs, disable only RSA
+# - component_test_psa_crypto_config_reference_ecc_ffdh_no_bignum
+#       - this is the reference component of the above
+#       - it still disables RSA, but it uses builtin EC and FFDH algs
+#
+# This function accepts 2 parameters:
+# $1: a boolean value which states if we are testing an accelerated scenario
+#     or not.
+# $2: a string value which states which components are tested. Allowed values
+#     are "ECC" or "ECC_DH".
+config_psa_crypto_config_accel_ecc_ffdh_no_bignum() {
     DRIVER_ONLY="$1"
+    TEST_TARGET="$2"
     # start with full config for maximum coverage (also enables USE_PSA)
     helper_libtestdriver1_adjust_config "full"
 
@@ -2706,13 +2719,23 @@
     scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
     scripts/config.py unset MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
 
-    # Disable FFDH because it also depends on BIGNUM.
-    scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_FFDH
-    scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_KEY_TYPE_DH_[0-9A-Z_a-z]*"
-    scripts/config.py unset MBEDTLS_DHM_C
-    # Also disable key exchanges that depend on FFDH
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
-    scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+    if [ "$TEST_TARGET" = "ECC" ]; then
+        # When testing ECC only, we disable FFDH support, both from builtin and
+        # PSA sides, and also disable the key exchanges that depend on DHM.
+        scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_FFDH
+        scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_KEY_TYPE_DH_[0-9A-Z_a-z]*"
+        scripts/config.py unset MBEDTLS_DHM_C
+        scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+        scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+    else
+        # When testing ECC and DH instead, we disable DHM and depending key
+        # exchanges only in the accelerated build
+        if [ "$DRIVER_ONLY" -eq 1 ]; then
+            scripts/config.py unset MBEDTLS_DHM_C
+            scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+            scripts/config.py unset MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+        fi
+    fi
 
     # Restartable feature is not yet supported by PSA. Once it will in
     # the future, the following line could be removed (see issues
@@ -2720,15 +2743,32 @@
     scripts/config.py unset MBEDTLS_ECP_RESTARTABLE
 }
 
-# Build and test a configuration where driver accelerates all EC algs while
-# all support and dependencies from ECP and ECP_LIGHT are removed on the library
-# side.
+# Common helper used by:
+# - component_test_psa_crypto_config_accel_ecc_no_bignum
+# - component_test_psa_crypto_config_accel_ecc_ffdh_no_bignum
 #
-# Keep in sync with component_test_psa_crypto_config_reference_ecc_no_bignum()
-component_test_psa_crypto_config_accel_ecc_no_bignum () {
-    msg "build: full + accelerated EC algs + USE_PSA - ECP - BIGNUM"
+# The goal is to build and test accelerating either:
+# - ECC only or
+# - both ECC and FFDH
+#
+# It is meant to be used in conjunction with
+# common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum() for drivers
+# coverage analysis in the "analyze_outcomes.py" script.
+common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum () {
+    TEST_TARGET="$1"
 
-    # Algorithms and key types to accelerate
+    # This is an internal helper to simplify text message handling
+    if [ "$TEST_TARGET" = "ECC_DH" ]; then
+        ACCEL_TEXT="ECC/FFDH"
+        REMOVED_TEXT="ECP - DH"
+    else
+        ACCEL_TEXT="ECC"
+        REMOVED_TEXT="ECP"
+    fi
+
+    msg "build: full + accelerated $ACCEL_TEXT algs + USE_PSA - $REMOVED_TEXT - BIGNUM"
+
+    # By default we accelerate all EC keys/algs
     loc_accel_list="ALG_ECDSA ALG_DETERMINISTIC_ECDSA \
                     ALG_ECDH \
                     ALG_JPAKE \
@@ -2737,12 +2777,22 @@
                     KEY_TYPE_ECC_KEY_PAIR_EXPORT \
                     KEY_TYPE_ECC_KEY_PAIR_GENERATE \
                     KEY_TYPE_ECC_PUBLIC_KEY"
+    # Optionally we can also add DH to the list of accelerated items
+    if [ "$TEST_TARGET" = "ECC_DH" ]; then
+        loc_accel_list="$loc_accel_list \
+                        ALG_FFDH \
+                        KEY_TYPE_DH_KEY_PAIR_BASIC \
+                        KEY_TYPE_DH_KEY_PAIR_IMPORT \
+                        KEY_TYPE_DH_KEY_PAIR_EXPORT \
+                        KEY_TYPE_DH_KEY_PAIR_GENERATE \
+                        KEY_TYPE_DH_PUBLIC_KEY"
+    fi
 
     # Configure
     # ---------
 
     # Set common configurations between library's and driver's builds
-    config_psa_crypto_config_accel_ecc_no_bignum 1
+    config_psa_crypto_config_accel_ecc_ffdh_no_bignum 1 "$TEST_TARGET"
 
     # Build
     # -----
@@ -2759,41 +2809,73 @@
     not grep mbedtls_ecdsa_ library/ecdsa.o
     not grep mbedtls_ecdh_ library/ecdh.o
     not grep mbedtls_ecjpake_ library/ecjpake.o
-    # Also ensure that ECP, RSA, DHM or BIGNUM modules were not re-enabled
+    # Also ensure that ECP, RSA, [DHM] or BIGNUM modules were not re-enabled
     not grep mbedtls_ecp_ library/ecp.o
     not grep mbedtls_rsa_ library/rsa.o
-    not grep mbedtls_dhm_ library/dhm.o
     not grep mbedtls_mpi_ library/bignum.o
+    not grep mbedtls_dhm_ library/dhm.o
 
     # Run the tests
     # -------------
 
-    msg "test suites: full + accelerated EC algs + USE_PSA - ECP - BIGNUM"
+    msg "test suites: full + accelerated $ACCEL_TEXT algs + USE_PSA - $REMOVED_TEXT - DHM - BIGNUM"
+
     make test
 
-    # The following will be enabled in #7756
-    msg "ssl-opt: full + accelerated EC algs + USE_PSA - ECP - BIGNUM"
+    msg "ssl-opt: full + accelerated $ACCEL_TEXT algs + USE_PSA - $REMOVED_TEXT - BIGNUM"
     tests/ssl-opt.sh
 }
 
-# Reference function used for driver's coverage analysis in analyze_outcomes.py
-# in conjunction with component_test_psa_crypto_config_accel_ecc_no_bignum().
-# Keep in sync with its accelerated counterpart.
-component_test_psa_crypto_config_reference_ecc_no_bignum () {
-    msg "build: full + non accelerated EC algs + USE_PSA"
+# Common helper used by:
+# - component_test_psa_crypto_config_reference_ecc_no_bignum
+# - component_test_psa_crypto_config_reference_ecc_ffdh_no_bignum
+#
+# The goal is to build and test a reference scenario (i.e. with builtin
+# components) compared to the ones used in
+# common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum() above.
+#
+# It is meant to be used in conjunction with
+# common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum() for drivers'
+# coverage analysis in "analyze_outcomes.py" script.
+common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum () {
+    TEST_TARGET="$1"
 
-    config_psa_crypto_config_accel_ecc_no_bignum 0
+    # This is an internal helper to simplify text message handling
+    if [ "$TEST_TARGET" = "ECC_DH" ]; then
+        ACCEL_TEXT="ECC/FFDH"
+    else
+        ACCEL_TEXT="ECC"
+    fi
+
+    msg "build: full + non accelerated $ACCEL_TEXT algs + USE_PSA"
+
+    config_psa_crypto_config_accel_ecc_ffdh_no_bignum 0 "$TEST_TARGET"
 
     make
 
     msg "test suites: full + non accelerated EC algs + USE_PSA"
     make test
 
-    # The following will be enabled in #7756
-    msg "ssl-opt: full + non accelerated EC algs + USE_PSA"
+    msg "ssl-opt: full + non accelerated $ACCEL_TEXT algs + USE_PSA"
     tests/ssl-opt.sh
 }
 
+component_test_psa_crypto_config_accel_ecc_no_bignum () {
+    common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum "ECC"
+}
+
+component_test_psa_crypto_config_reference_ecc_no_bignum () {
+    common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum "ECC"
+}
+
+component_test_psa_crypto_config_accel_ecc_ffdh_no_bignum () {
+    common_test_psa_crypto_config_accel_ecc_ffdh_no_bignum "ECC_DH"
+}
+
+component_test_psa_crypto_config_reference_ecc_ffdh_no_bignum () {
+    common_test_psa_crypto_config_reference_ecc_ffdh_no_bignum "ECC_DH"
+}
+
 # Helper function used in:
 # - component_test_psa_crypto_config_accel_all_curves_except_p192
 # - component_test_psa_crypto_config_accel_all_curves_except_x25519
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index 3b91bfb..7b0ab3d 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -325,7 +325,7 @@
             }
         }
     },
-    'analyze_driver_vs_reference_no_bignum': {
+    'analyze_driver_vs_reference_ecc_no_bignum': {
         'test_function': do_analyze_driver_vs_reference,
         'args': {
             'component_ref': 'test_psa_crypto_config_reference_ecc_no_bignum',
@@ -418,6 +418,100 @@
             }
         }
     },
+    'analyze_driver_vs_reference_ecc_ffdh_no_bignum': {
+        'test_function': do_analyze_driver_vs_reference,
+        'args': {
+            'component_ref': 'test_psa_crypto_config_reference_ecc_ffdh_no_bignum',
+            'component_driver': 'test_psa_crypto_config_accel_ecc_ffdh_no_bignum',
+            'ignored_suites': [
+                # Ignore test suites for the modules that are disabled in the
+                # accelerated test case.
+                'ecp',
+                'ecdsa',
+                'ecdh',
+                'ecjpake',
+                'bignum_core',
+                'bignum_random',
+                'bignum_mod',
+                'bignum_mod_raw',
+                'bignum.generated',
+                'bignum.misc',
+                'dhm',
+            ],
+            'ignored_tests': {
+                'test_suite_random': [
+                    'PSA classic wrapper: ECDSA signature (SECP256R1)',
+                ],
+                'test_suite_psa_crypto': [
+                    'PSA key derivation: HKDF-SHA-256 -> ECC secp256r1',
+                    'PSA key derivation: HKDF-SHA-256 -> ECC secp256r1 (1 redraw)',
+                    'PSA key derivation: HKDF-SHA-256 -> ECC secp256r1, exercise ECDSA',
+                    'PSA key derivation: HKDF-SHA-256 -> ECC secp384r1',
+                    'PSA key derivation: HKDF-SHA-256 -> ECC secp521r1 #0',
+                    'PSA key derivation: HKDF-SHA-256 -> ECC secp521r1 #1',
+                    'PSA key derivation: bits=7 invalid for ECC BRAINPOOL_P_R1 (ECC enabled)',
+                    'PSA key derivation: bits=7 invalid for ECC SECP_K1 (ECC enabled)',
+                    'PSA key derivation: bits=7 invalid for ECC SECP_R1 (ECC enabled)',
+                    'PSA key derivation: bits=7 invalid for ECC SECP_R2 (ECC enabled)',
+                    'PSA key derivation: bits=7 invalid for ECC SECT_K1 (ECC enabled)',
+                    'PSA key derivation: bits=7 invalid for ECC SECT_R1 (ECC enabled)',
+                    'PSA key derivation: bits=7 invalid for ECC SECT_R2 (ECC enabled)',
+                ],
+                'test_suite_pkparse': [
+                    # See the description provided above in the
+                    # analyze_driver_vs_reference_no_ecp_at_all component.
+                    'Parse EC Key #10a (SEC1 PEM, secp384r1, compressed)',
+                    'Parse EC Key #11a (SEC1 PEM, secp521r1, compressed)',
+                    'Parse EC Key #12a (SEC1 PEM, bp256r1, compressed)',
+                    'Parse EC Key #13a (SEC1 PEM, bp384r1, compressed)',
+                    'Parse EC Key #14a (SEC1 PEM, bp512r1, compressed)',
+                    'Parse EC Key #2a (SEC1 PEM, secp192r1, compressed)',
+                    'Parse EC Key #8a (SEC1 PEM, secp224r1, compressed)',
+                    'Parse EC Key #9a (SEC1 PEM, secp256r1, compressed)',
+                    'Parse Public EC Key #2a (RFC 5480, PEM, secp192r1, compressed)',
+                    'Parse Public EC Key #3a (RFC 5480, secp224r1, compressed)',
+                    'Parse Public EC Key #4a (RFC 5480, secp256r1, compressed)',
+                    'Parse Public EC Key #5a (RFC 5480, secp384r1, compressed)',
+                    'Parse Public EC Key #6a (RFC 5480, secp521r1, compressed)',
+                    'Parse Public EC Key #7a (RFC 5480, brainpoolP256r1, compressed)',
+                    'Parse Public EC Key #8a (RFC 5480, brainpoolP384r1, compressed)',
+                    'Parse Public EC Key #9a (RFC 5480, brainpoolP512r1, compressed)',
+                ],
+                'test_suite_asn1parse': [
+                    # This test depends on BIGNUM_C
+                    'INTEGER too large for mpi',
+                ],
+                'test_suite_asn1write': [
+                    # Following tests depends on BIGNUM_C
+                    'ASN.1 Write mpi 0 (1 limb)',
+                    'ASN.1 Write mpi 0 (null)',
+                    'ASN.1 Write mpi 0x100',
+                    'ASN.1 Write mpi 0x7f',
+                    'ASN.1 Write mpi 0x7f with leading 0 limb',
+                    'ASN.1 Write mpi 0x80',
+                    'ASN.1 Write mpi 0x80 with leading 0 limb',
+                    'ASN.1 Write mpi 0xff',
+                    'ASN.1 Write mpi 1',
+                    'ASN.1 Write mpi, 127*8 bits',
+                    'ASN.1 Write mpi, 127*8+1 bits',
+                    'ASN.1 Write mpi, 127*8-1 bits',
+                    'ASN.1 Write mpi, 255*8 bits',
+                    'ASN.1 Write mpi, 255*8-1 bits',
+                    'ASN.1 Write mpi, 256*8-1 bits',
+                ],
+                'test_suite_debug': [
+                    # Following tests depends on BIGNUM_C
+                    'Debug print mbedtls_mpi #2: 3 bits',
+                    'Debug print mbedtls_mpi: 0 (empty representation)',
+                    'Debug print mbedtls_mpi: 0 (non-empty representation)',
+                    'Debug print mbedtls_mpi: 49 bits',
+                    'Debug print mbedtls_mpi: 759 bits',
+                    'Debug print mbedtls_mpi: 764 bits #1',
+                    'Debug print mbedtls_mpi: 764 bits #2',
+                ],
+            }
+        }
+    },
     'analyze_driver_vs_reference_ffdh_alg': {
         'test_function': do_analyze_driver_vs_reference,
         'args': {
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 2396590..88bdd6c 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -9764,7 +9764,7 @@
     unsigned char *first_export = NULL;
     unsigned char *second_export = NULL;
     size_t export_size = PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits);
-    size_t first_exported_length;
+    size_t first_exported_length = 0;
     size_t second_exported_length;
 
     if (usage_flags & PSA_KEY_USAGE_EXPORT) {
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 7af9de9..e1db717 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -184,11 +184,11 @@
 
 X509 CRT information Bitstring in subject name
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA1
-x509_cert_info:"data_files/parse_input/bitstring-in-dn.pem":"cert. version     \: 3\nserial number     \: 02\nissuer name       \: CN=Test CA 01, ST=Ecnivorp, C=XX, emailAddress=tca@example.com, O=Test CA Authority\nsubject name      \: C=XX, O=tca, ST=Ecnivorp, OU=TCA, CN=Client, emailAddress=client@example.com, serialNumber=7101012255, uniqueIdentifier=?7101012255\nissued  on        \: 2015-03-11 12\:06\:51\nexpires on        \: 2025-03-08 12\:06\:51\nsigned using      \: RSA with SHA1\nRSA key size      \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name  \:\n    rfc822Name \: client@example.com\next key usage     \: TLS Web Client Authentication\n"
+x509_cert_info:"data_files/parse_input/bitstring-in-dn.pem":"cert. version     \: 3\nserial number     \: 02\nissuer name       \: CN=Test CA 01, ST=Ecnivorp, C=XX, emailAddress=tca@example.com, O=Test CA Authority\nsubject name      \: C=XX, O=tca, ST=Ecnivorp, OU=TCA, CN=Client, emailAddress=client@example.com, serialNumber=7101012255, uniqueIdentifier=#030B0037313031303132323535\nissued  on        \: 2015-03-11 12\:06\:51\nexpires on        \: 2025-03-08 12\:06\:51\nsigned using      \: RSA with SHA1\nRSA key size      \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name  \:\n    rfc822Name \: client@example.com\next key usage     \: TLS Web Client Authentication\n"
 
 X509 CRT information Non-ASCII string in issuer name and subject name
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA256
-x509_cert_info:"data_files/parse_input/non-ascii-string-in-issuer.crt":"cert. version     \: 3\nserial number     \: 05\:E6\:53\:E7\:1B\:74\:F0\:B5\:D3\:84\:6D\:0C\:6D\:DC\:FA\:3F\:A4\:5A\:2B\:E0\nissuer name       \: C=JP, ST=Tokyo, O=?????????????????? Ltd, CN=?????????????????? CA\nsubject name      \: C=JP, ST=Tokyo, O=?????????????????? Ltd, CN=?????????????????? CA\nissued  on        \: 2020-05-20 16\:17\:23\nexpires on        \: 2020-06-19 16\:17\:23\nsigned using      \: RSA with SHA-256\nRSA key size      \: 2048 bits\nbasic constraints \: CA=true\n"
+x509_cert_info:"data_files/parse_input/non-ascii-string-in-issuer.crt":"cert. version     \: 3\nserial number     \: 05\:E6\:53\:E7\:1B\:74\:F0\:B5\:D3\:84\:6D\:0C\:6D\:DC\:FA\:3F\:A4\:5A\:2B\:E0\nissuer name       \: C=JP, ST=Tokyo, O=\\C3\\A3\\C2\\83\\C2\\86\\C3\\A3\\C2\\82\\C2\\B9\\C3\\A3\\C2\\83\\C2\\88 Ltd, CN=\\C3\\A3\\C2\\83\\C2\\86\\C3\\A3\\C2\\82\\C2\\B9\\C3\\A3\\C2\\83\\C2\\88 CA\nsubject name      \: C=JP, ST=Tokyo, O=\\C3\\A3\\C2\\83\\C2\\86\\C3\\A3\\C2\\82\\C2\\B9\\C3\\A3\\C2\\83\\C2\\88 Ltd, CN=\\C3\\A3\\C2\\83\\C2\\86\\C3\\A3\\C2\\82\\C2\\B9\\C3\\A3\\C2\\83\\C2\\88 CA\nissued  on        \: 2020-05-20 16\:17\:23\nexpires on        \: 2020-06-19 16\:17\:23\nsigned using      \: RSA with SHA-256\nRSA key size      \: 2048 bits\nbasic constraints \: CA=true\n"
 
 X509 CRT information Parsing IPv4 and IPv6 IP names
 depends_on:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C
@@ -447,6 +447,18 @@
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA1
 mbedtls_x509_dn_gets:"data_files/server1.commas.crt":"subject":"C=NL, O=PolarSSL\\, Commas, CN=PolarSSL Server 1"
 
+X509 Get Distinguished Name #6
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA1
+mbedtls_x509_dn_gets:"data_files/server1.hashsymbol.crt":"subject":"C=NL, O=\\#PolarSSL, CN=PolarSSL Server 1"
+
+X509 Get Distinguished Name #7
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA1
+mbedtls_x509_dn_gets:"data_files/server1.spaces.crt":"subject":"C=NL, O=\\ PolarSSL\\ , CN=PolarSSL Server 1"
+
+X509 Get Distinguished Name #8
+depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA1
+mbedtls_x509_dn_gets:"data_files/server1.asciichars.crt":"subject":"C=NL, O=\\E6\\9E\\81\\E5\\9C\\B0SSL, CN=PolarSSL Server 1"
+
 X509 Get Modified DN #1
 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA1
 mbedtls_x509_dn_gets_subject_replace:"data_files/server1.crt":"Modified":"C=NL, O=Modified, CN=PolarSSL Server 1":0
@@ -2373,7 +2385,7 @@
 
 X509 CRT ASN1 (Name with composite RDN)
 depends_on:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA1
-x509parse_crt:"3082029f30820208a00302010202044c20e3bd300d06092a864886f70d01010505003056310b3009060355040613025553310b300906035504080c0243413121301f060355040a0c18496e7465726e6574205769646769747320507479204c74643117301506035504030c0e4672616e6b656e63657274204341301e170d3133303830323135313433375a170d3135303831373035353433315a3081d1310b3009060355040613025553311330110603550408130a57617368696e67746f6e31133011060b2b0601040182373c0201031302555331193017060b2b0601040182373c020102130844656c6177617265311a3018060355040a1311417574686f72697a652e4e6574204c4c43311d301b060355040f131450726976617465204f7267616e697a6174696f6e312a300e06035504051307343336393139313018060355040313117777772e617574686f72697a652e6e6574311630140603550407130d53616e204672616e636973636f30819f300d06092a864886f70d010101050003818d0030818902818100d885c62e209b6ac005c64f0bcfdaac1f2b67a18802f75b08851ff933deed888b7b68a62fcabdb21d4a8914becfeaaa1b7e08a09ffaf9916563586dc95e2877262b0b5f5ec27eb4d754aa6facd1d39d25b38a2372891bacdd3e919f791ed25704e8920e380e5623a38e6a23935978a3aec7a8e761e211d42effa2713e44e7de0b0203010001300d06092a864886f70d010105050003818100092f7424d3f6da4b8553829d958ed1980b9270b42c0d3d5833509a28c66bb207df9f3c51d122065e00b87c08c2730d2745fe1c279d16fae4d53b4bf5bdfa3631fceeb2e772b6b08a3eca5a2e2c687aefd23b4b73bf77ac6099711342cf070b35c6f61333a7cbf613d8dd4bd73e9df34bcd4284b0b4df57c36c450613f11e5dac":"cert. version     \: 3\nserial number     \: 4C\:20\:E3\:BD\nissuer name       \: C=US, ST=CA, O=Internet Widgits Pty Ltd, CN=Frankencert CA\nsubject name      \: C=US, ST=Washington, ??=US, ??=Delaware, O=Authorize.Net LLC, ??=Private Organization, serialNumber=4369191 + CN=www.authorize.net, L=San Francisco\nissued  on        \: 2013-08-02 15\:14\:37\nexpires on        \: 2015-08-17 05\:54\:31\nsigned using      \: RSA with SHA1\nRSA key size      \: 1024 bits\n":0
+x509parse_crt:"3082029f30820208a00302010202044c20e3bd300d06092a864886f70d01010505003056310b3009060355040613025553310b300906035504080c0243413121301f060355040a0c18496e7465726e6574205769646769747320507479204c74643117301506035504030c0e4672616e6b656e63657274204341301e170d3133303830323135313433375a170d3135303831373035353433315a3081d1310b3009060355040613025553311330110603550408130a57617368696e67746f6e31133011060b2b0601040182373c0201031302555331193017060b2b0601040182373c020102130844656c6177617265311a3018060355040a1311417574686f72697a652e4e6574204c4c43311d301b060355040f131450726976617465204f7267616e697a6174696f6e312a300e06035504051307343336393139313018060355040313117777772e617574686f72697a652e6e6574311630140603550407130d53616e204672616e636973636f30819f300d06092a864886f70d010101050003818d0030818902818100d885c62e209b6ac005c64f0bcfdaac1f2b67a18802f75b08851ff933deed888b7b68a62fcabdb21d4a8914becfeaaa1b7e08a09ffaf9916563586dc95e2877262b0b5f5ec27eb4d754aa6facd1d39d25b38a2372891bacdd3e919f791ed25704e8920e380e5623a38e6a23935978a3aec7a8e761e211d42effa2713e44e7de0b0203010001300d06092a864886f70d010105050003818100092f7424d3f6da4b8553829d958ed1980b9270b42c0d3d5833509a28c66bb207df9f3c51d122065e00b87c08c2730d2745fe1c279d16fae4d53b4bf5bdfa3631fceeb2e772b6b08a3eca5a2e2c687aefd23b4b73bf77ac6099711342cf070b35c6f61333a7cbf613d8dd4bd73e9df34bcd4284b0b4df57c36c450613f11e5dac":"cert. version     \: 3\nserial number     \: 4C\:20\:E3\:BD\nissuer name       \: C=US, ST=CA, O=Internet Widgits Pty Ltd, CN=Frankencert CA\nsubject name      \: C=US, ST=Washington, 1.3.6.1.4.1.311.60.2.1.3=#13025553, 1.3.6.1.4.1.311.60.2.1.2=#130844656C6177617265, O=Authorize.Net LLC, 2.5.4.15=#131450726976617465204F7267616E697A6174696F6E, serialNumber=4369191 + CN=www.authorize.net, L=San Francisco\nissued  on        \: 2013-08-02 15\:14\:37\nexpires on        \: 2015-08-17 05\:54\:31\nsigned using      \: RSA with SHA1\nRSA key size      \: 1024 bits\n":0
 
 X509 CRT ASN1 (Name with PKCS9 email)
 depends_on:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA256
diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
index 0848550..37679c1 100644
--- a/tests/suites/test_suite_x509write.data
+++ b/tests/suites/test_suite_x509write.data
@@ -170,7 +170,7 @@
 mbedtls_x509_string_to_names:"C=NL,O=Offspark\\, Inc., OU=PolarSSL":"C=NL, O=Offspark\\, Inc., OU=PolarSSL":0
 
 X509 String to Names #2
-mbedtls_x509_string_to_names:"C=NL, O=Offspark, Inc., OU=PolarSSL":"":MBEDTLS_ERR_X509_UNKNOWN_OID
+mbedtls_x509_string_to_names:"C=NL, O=Offspark, Inc., OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
 
 X509 String to Names #3 (Name precisely 255 bytes)
 mbedtls_x509_string_to_names:"C=NL, O=123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345,OU=PolarSSL":"C=NL, O=123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345, OU=PolarSSL":0
@@ -184,8 +184,56 @@
 X509 String to Names #6 (Escape at end)
 mbedtls_x509_string_to_names:"C=NL, O=Offspark\\":"":MBEDTLS_ERR_X509_INVALID_NAME
 
-X509 String to Names #6 (Invalid, no '=' or ',')
+X509 String to Names #7 (Invalid, no '=' or ',')
 mbedtls_x509_string_to_names:"ABC123":"":MBEDTLS_ERR_X509_INVALID_NAME
 
+X509 String to Names #8 (Escaped valid characters)
+mbedtls_x509_string_to_names:"C=NL, O=Offspark\\+ \\> \\=, OU=PolarSSL":"C=NL, O=Offspark\\+ \\> \\=, OU=PolarSSL":0
+
+X509 String to Names #9 (Escaped ascii hexpairs uppercase encoded)
+mbedtls_x509_string_to_names:"C=NL, O=\\4F\\66\\66\\73\\70\\61\\72\\6B, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0
+
+X509 String to Names #10 (Escaped ascii hexpairs lowercase encoded)
+mbedtls_x509_string_to_names:"C=NL, O=\\4f\\66\\66\\73\\70\\61\\72\\6b, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0
+
+X509 String to Names #11 (Invalid hexpair escape at end of string)
+mbedtls_x509_string_to_names:"C=NL, O=\\4f\\66\\66\\73\\70\\61\\72\\6, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
+
+X509 String to Names #12 (Reject escaped null hexpair)
+mbedtls_x509_string_to_names:"C=NL, O=Of\\00spark, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
+
+X509 String to Names #13 (Invalid hexpairs)
+mbedtls_x509_string_to_names:"C=NL, O=Of\\flspark, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
+
+X509 String to Names #14 (Accept numercoid/hexstring)
+mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C084F6666737061726B, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0
+
+X509 String to Names #15 (Odd length DER hexstring)
+mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C084F6666737061726, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
+
+X509 String to Names #16 (Length mismatch DER hexstring)
+mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C0B4F6666737061726B, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
+
+X509 String to Names #17 (Invalid OID)
+mbedtls_x509_string_to_names:"C=NL, 10.5.4.10=#0C084F6666737061726B, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
+
+X509 String to Names #18 (short name and hexstring)
+mbedtls_x509_string_to_names:"C=NL, O=#0C084F6666737061726B, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0
+
+X509 String to Names #19 (Accept non-ascii hexpairs)
+mbedtls_x509_string_to_names:"C=NL, O=Of\\CCspark, OU=PolarSSL":"C=NL, O=Of\\CCspark, OU=PolarSSL":0
+
+X509 String to Names #20 (Reject empty AttributeValue)
+mbedtls_x509_string_to_names:"C=NL, O=, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
+
+X509 Round trip test (Escaped characters)
+mbedtls_x509_string_to_names:"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":0
+
+X509 Round trip test (hexstring output for non string input)
+mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#03084F6666737061726B, OU=PolarSSL":"C=NL, O=#03084F6666737061726B, OU=PolarSSL":0
+
+X509 Round trip test (numercoid hexstring output for unknown OID)
+mbedtls_x509_string_to_names:"C=NL, 2.5.4.10.234.532=#0C084F6666737061726B, OU=PolarSSL":"C=NL, 2.5.4.10.234.532=#0C084F6666737061726B, OU=PolarSSL":0
+
 Check max serial length
 x509_set_serial_check: