Merge pull request #1638 from dgreen-arm/check-names-rewrite

Rewrite check-names.sh in python
diff --git a/ChangeLog.d/muladdc-amd64-memory.txt b/ChangeLog.d/muladdc-amd64-memory.txt
deleted file mode 100644
index b834331..0000000
--- a/ChangeLog.d/muladdc-amd64-memory.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Bugfix
-   * Fix missing constraints on x86_64 assembly code for bignum multiplication
-     that broke some bignum operations with (at least) Clang 12.
-     Fixes #4116, #4786, #4917.
diff --git a/ChangeLog.d/muladdc-memory.txt b/ChangeLog.d/muladdc-memory.txt
new file mode 100644
index 0000000..218be5a
--- /dev/null
+++ b/ChangeLog.d/muladdc-memory.txt
@@ -0,0 +1,5 @@
+Bugfix
+   * Fix missing constraints on x86_64 and aarch64 assembly code
+     for bignum multiplication that broke some bignum operations with
+     (at least) Clang 12.
+     Fixes #4116, #4786, #4917, #4962.
diff --git a/docs/use-psa-crypto.md b/docs/use-psa-crypto.md
new file mode 100644
index 0000000..6ec2dca
--- /dev/null
+++ b/docs/use-psa-crypto.md
@@ -0,0 +1,204 @@
+This document describes the compile-time configuration option
+`MBEDTLS_USE_PSA_CRYPTO` from a user's perspective, more specifically its
+current effects as well as the parts that aren't covered yet.
+
+Current effects
+===============
+
+General limitations
+-------------------
+
+Compile-time: enabling `MBEDTLS_USE_PSA_CRYPTO` requires
+`MBEDTLS_ECP_RESTARTABLE` and
+`MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER` to be disabled.
+
+Effect: `MBEDTLS_USE_PSA_CRYPTO` currently has no effect on TLS 1.3 (which is
+itself experimental and only partially supported so far): TLS 1.3 always uses
+the legacy APIs even when this option is set.
+
+Stability: any API that's only available when `MBEDTLS_USE_PSA_CRYPTO` is
+defined is considered experimental and may change in incompatible ways at any
+time. Said otherwise, these APIs are explicitly excluded from the usual API
+stability promises.
+
+New APIs / API extensions
+-------------------------
+
+Some of these APIs are meant for the application to use in place of
+pre-existing APIs, in order to get access to the benefits; in the sub-sections
+below these are indicated by "Use in (X.509 and) TLS: opt-in", meaning that
+this requires changes to the application code for the (X.509 and) TLS layers
+to pick up the improvements.
+
+Some of these APIs are mostly meant for internal use by the TLS (and X.509)
+layers; they are indicated below by "Use in (X.509 and) TLS: automatic",
+meaning that no changes to the application code are required for the TLS (and
+X.509) layers to pick up the improvements.
+
+### PSA-held (opaque) keys in the PK layer
+
+There is a new API function `mbedtls_pk_setup_opaque()` that can be used to
+wrap a PSA keypair into a PK context. The key can be used for private-key
+operations and its public part can be exported.
+
+Benefits: isolation of long-term secrets, use of PSA Crypto drivers.
+
+Limitations: only for private keys, only ECC. (That is, only ECDSA signature
+generation. Note: currently this will use randomized ECDSA while Mbed TLS uses
+deterministic ECDSA by default.) The following operations are not supported
+with a context set this way, while they would be available with a normal
+`ECKEY` context: `mbedtls_pk_verify()`, `mbedtls_pk_check_pair()`,
+`mbedtls_pk_debug()`.
+
+Use in X.509 and TLS: opt-in. The application needs to construct the PK context
+using the new API in order to get the benefits; it can then pass the
+resulting context to the following existing APIs:
+
+- `mbedtls_ssl_conf_own_cert()` or `mbedtls_ssl_set_hs_own_cert()` to use the
+  key together with a certificate for ECDSA-based key exchanges (note: while
+this is supported on both sides, it's currently only tested client-side);
+- `mbedtls_x509write_csr_set_key()` to generate a CSR (certificate signature
+  request).
+
+In the TLS and X.509 API, there are two other functions which accept a key or
+keypair as a PK context: `mbedtls_x509write_crt_set_subject_key()` and
+`mbedtls_x509write_crt_set_issuer_key()`. Use of opaque contexts here probably
+works but is so far untested.
+
+### PSA-held (opaque) keys for TLS pre-shared keys (PSK)
+
+There are two new API functions `mbedtls_ssl_conf_psk_opaque()` and
+`mbedtls_ssl_set_hs_psk_opaque()`. Call one of these from an application to
+register a PSA key for use with a PSK key exchange.
+
+Benefits: isolation of long-term secrets.
+
+Limitations: the key can only be used with "pure"
+PSK key exchanges (ciphersuites starting with `TLS_PSK_WITH_`), to the
+exclusion of RSA-PSK, DHE-PSK and ECDHE-PSK key exchanges. It is the responsibility of
+the user to make sure that when provisioning an opaque pre-shared key, the
+only PSK ciphersuites that can be negotiated are "pure" PSK; other XXX-PSK key
+exchanges will result in a handshake failure with the handshake function
+returning `MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE`.
+
+Use in TLS: opt-in. The application needs to register the key using the new
+APIs to get the benefits.
+
+### PSA-based operations in the Cipher layer
+
+There is a new API function `mbedtls_cipher_setup_psa()` to set up a context
+that will call PSA to store the key and perform the operations.
+
+Benefits: use of PSA Crypto drivers; partial isolation of short-term secrets
+(still generated outside of PSA, but then held by PSA).
+
+Limitations: the key is still passed in the clear by the application. The
+multi-part APIs are not supported, only the one-shot APIs. The only modes
+supported are ECB, CBC without padding, GCM and CCM (this excludes stream
+ciphers and ChachaPoly); the only cipher supported is AES (this excludes Aria,
+Camellia, and ChachaPoly). (Note: ECB is currently not tested.) (Note: it is
+possible to perform multiple one-shot operations with the same context;
+however this is not unit-tested, only tested via usage in TLS.)
+
+Use in TLS: automatic. Used when the cipher and mode is supported (with
+gracious fallback to the legacy API otherwise) in all places where a cipher is
+used. There are two such places: in `ssl_tls.c` for record protection, and in
+`ssl_ticket.c` for protecting tickets we issue.
+
+Internal changes
+----------------
+
+All of these internal changes are active as soon as `MBEDTLS_USE_PSA_CRYPTO`
+is enabled, no change required on the application side.
+
+### TLS: cipher operations based on PSA
+
+See "PSA-based operations in the Cipher layer" above.
+
+### PK layer: ECDSA verification based on PSA
+
+Scope: `mbedtls_pk_verify()` will call to PSA for ECDSA signature
+verification.
+
+Benefits: use of PSA Crypto drivers.
+
+Use in TLS and X.509: in all places where an ECDSA signature is verified.
+
+### TLS: ECDHE computation based on PSA
+
+Scope: Client-side, for ECDHE-RSA and ECDHE-ECDSA key exchanges, the
+computation of the ECDHE key exchange is done by PSA.
+
+Limitations: client-side only, ECDHE-PSK not covered
+
+Benefits: use of PSA Crypto drivers.
+
+### TLS: handshake hashes and PRF computed with PSA
+
+Scope: with TLS 1.2, the following are computed with PSA:
+- the running handshake hashes;
+- the hash of the ServerKeyExchange part that is signed;
+- the `verify_data` part of the Finished message;
+- the TLS PRF.
+
+Benefits: use of PSA Crypto drivers.
+
+### X.509: some hashes computed with PSA
+
+Scope: the following hashes are computed with PSA:
+- when verifying a certificate chain, hash of the child for verifying the
+  parent's signature;
+- when writing a CSR, hash of the request for self-signing the request.
+
+Benefits: use of PSA Crypto drivers.
+
+Parts that are not covered yet
+==============================
+
+This is only a high-level overview, grouped by theme
+
+TLS: 1.3 experimental support
+-----------------------------
+
+No part of the experimental support for TLS 1.3 is covered at the moment.
+
+TLS: key exchanges / asymmetric crypto
+--------------------------------------
+
+The following key exchanges are not covered at all:
+
+- RSA
+- DHE-RSA
+- DHE-PSK
+- RSA-PSK
+- ECDHE-PSK
+- ECDH-RSA
+- ECDH-ECDSA
+- ECJPAKE
+
+The following key exchanges are only partially covered:
+
+- ECDHE-RSA: RSA operations are not covered and, server-side, the ECDHE
+  operation isn't either
+- ECDHE-ECDSA: server-side, the ECDHE operation isn't covered. (ECDSA
+  signature generation is only covered if using `mbedtls_pk_setup_opaque()`.)
+
+PSK if covered when the application uses `mbedtls_ssl_conf_psk_opaque()` or
+`mbedtls_ssl_set_hs_psk_opaque()`.
+
+TLS: symmetric crypto
+---------------------
+
+- some ciphers not supported via PSA yet: ARIA, Camellia, ChachaPoly (silent
+  fallback to the legacy APIs)
+- the HMAC part of the CBC and NULL ciphersuites
+- the HMAC computation in `ssl_cookie.c`
+
+X.509
+-----
+
+- most hash operations are still done via the legacy API, except the few that
+  are documented above as using PSA
+- RSA PKCS#1 v1.5 signature generation (from PSA-held keys)
+- RSA PKCS#1 v1.5 signature verification
+- RSA-PSS signature verification
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 3dbf722..adc317d 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -1718,15 +1718,13 @@
  * will still continue to work as usual, so enabling this option should not
  * break backwards compatibility.
  *
- * \warning The PSA Crypto API is in beta stage. While you're welcome to
- * experiment using it, incompatible API changes are still possible, and some
- * parts may not have reached the same quality as the rest of Mbed TLS yet.
+ * \note See docs/use-psa-crypto.md for a complete description of what this
+ * option currently does, and of parts that are not affected by it so far.
  *
- * \warning This option enables new Mbed TLS APIs that are dependent on the
- * PSA Crypto API, so can't come with the same stability guarantees as the
- * rest of the Mbed TLS APIs. You're welcome to experiment with them, but for
- * now, access to these APIs is opt-in (via enabling the present option), in
- * order to clearly differentiate them from the stable Mbed TLS APIs.
+ * \warning This option enables new Mbed TLS APIs which are currently
+ * considered experimental and may change in incompatible ways at any time.
+ * That is, the APIs enabled by this option are not covered by the usual
+ * promises of API stability.
  *
  * Requires: MBEDTLS_PSA_CRYPTO_C.
  *
@@ -2592,10 +2590,6 @@
  *
  * Enable the Platform Security Architecture cryptography API.
  *
- * \warning The PSA Crypto API is still beta status. While you're welcome to
- * experiment using it, incompatible API changes are still possible, and some
- * parts may not have reached the same quality as the rest of Mbed TLS yet.
- *
  * Module:  library/psa_crypto.c
  *
  * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
diff --git a/library/bn_mul.h b/library/bn_mul.h
index 328e765..b71ddd8 100644
--- a/library/bn_mul.h
+++ b/library/bn_mul.h
@@ -224,7 +224,7 @@
         "adcq   %%rdx, %%rcx\n"             \
         "addq   $8, %%rdi\n"
 
-#define MULADDC_STOP                        \
+#define MULADDC_STOP                                                 \
         : "+c" (c), "+D" (d), "+S" (s), "+m" (*(uint64_t (*)[16]) d) \
         : "b" (b), "m" (*(const uint64_t (*)[16]) s)                 \
         : "rax", "rdx", "r8"                                         \
@@ -240,18 +240,18 @@
 #define MULADDC_CORE                \
         "ldr x4, [%2], #8   \n\t"   \
         "ldr x5, [%1]       \n\t"   \
-        "mul x6, x4, %3     \n\t"   \
-        "umulh x7, x4, %3   \n\t"   \
+        "mul x6, x4, %4     \n\t"   \
+        "umulh x7, x4, %4   \n\t"   \
         "adds x5, x5, x6    \n\t"   \
         "adc x7, x7, xzr    \n\t"   \
         "adds x5, x5, %0    \n\t"   \
         "adc %0, x7, xzr    \n\t"   \
         "str x5, [%1], #8   \n\t"
 
-#define MULADDC_STOP                        \
-         : "+r" (c),  "+r" (d), "+r" (s)    \
-         : "r" (b)                          \
-         : "x4", "x5", "x6", "x7", "cc"     \
+#define MULADDC_STOP                                                    \
+         : "+r" (c),  "+r" (d), "+r" (s), "+m" (*(uint64_t (*)[16]) d)  \
+         : "r" (b), "m" (*(const uint64_t (*)[16]) s)                   \
+         : "x4", "x5", "x6", "x7", "cc"                                 \
     );
 
 #endif /* Aarch64 */
diff --git a/tests/compat.sh b/tests/compat.sh
index c2bef26..f4c611a 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -236,60 +236,46 @@
     G_CIPHERS=""
 }
 
+check_translation()
+{
+    if [ $1 -ne 0 ]; then
+        echo "translate_ciphers.py failed with exit code $1" >&2
+        echo "$2" >&2
+        exit 1
+    fi
+}
+
 # Ciphersuites that can be used with all peers.
 # Since we currently have three possible peers, each ciphersuite should appear
 # three times: in each peer's list (with the name that this peer uses).
 add_common_ciphersuites()
 {
+    CIPHERS=""
     case $TYPE in
 
         "ECDSA")
             if [ `minor_ver "$MODE"` -gt 0 ]
             then
-                M_CIPHERS="$M_CIPHERS                       \
+                CIPHERS="$CIPHERS                           \
                     TLS-ECDHE-ECDSA-WITH-NULL-SHA           \
                     TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA   \
                     TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA    \
                     TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA    \
                     "
-                G_CIPHERS="$G_CIPHERS                       \
-                    +ECDHE-ECDSA:+NULL:+SHA1                \
-                    +ECDHE-ECDSA:+3DES-CBC:+SHA1            \
-                    +ECDHE-ECDSA:+AES-128-CBC:+SHA1         \
-                    +ECDHE-ECDSA:+AES-256-CBC:+SHA1         \
-                    "
-                O_CIPHERS="$O_CIPHERS               \
-                    ECDHE-ECDSA-NULL-SHA            \
-                    ECDHE-ECDSA-DES-CBC3-SHA        \
-                    ECDHE-ECDSA-AES128-SHA          \
-                    ECDHE-ECDSA-AES256-SHA          \
-                    "
             fi
             if [ `minor_ver "$MODE"` -ge 3 ]
             then
-                M_CIPHERS="$M_CIPHERS                               \
+                CIPHERS="$CIPHERS                                   \
                     TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256         \
                     TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384         \
                     TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256         \
                     TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384         \
                     "
-                G_CIPHERS="$G_CIPHERS                               \
-                    +ECDHE-ECDSA:+AES-128-CBC:+SHA256               \
-                    +ECDHE-ECDSA:+AES-256-CBC:+SHA384               \
-                    +ECDHE-ECDSA:+AES-128-GCM:+AEAD                 \
-                    +ECDHE-ECDSA:+AES-256-GCM:+AEAD                 \
-                    "
-                O_CIPHERS="$O_CIPHERS               \
-                    ECDHE-ECDSA-AES128-SHA256       \
-                    ECDHE-ECDSA-AES256-SHA384       \
-                    ECDHE-ECDSA-AES128-GCM-SHA256   \
-                    ECDHE-ECDSA-AES256-GCM-SHA384   \
-                    "
             fi
             ;;
 
         "RSA")
-            M_CIPHERS="$M_CIPHERS                       \
+            CIPHERS="$CIPHERS                           \
                 TLS-DHE-RSA-WITH-AES-128-CBC-SHA        \
                 TLS-DHE-RSA-WITH-AES-256-CBC-SHA        \
                 TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA   \
@@ -303,58 +289,18 @@
                 TLS-RSA-WITH-NULL-MD5                   \
                 TLS-RSA-WITH-NULL-SHA                   \
                 "
-            G_CIPHERS="$G_CIPHERS                       \
-                +DHE-RSA:+AES-128-CBC:+SHA1             \
-                +DHE-RSA:+AES-256-CBC:+SHA1             \
-                +DHE-RSA:+CAMELLIA-128-CBC:+SHA1        \
-                +DHE-RSA:+CAMELLIA-256-CBC:+SHA1        \
-                +DHE-RSA:+3DES-CBC:+SHA1                \
-                +RSA:+AES-256-CBC:+SHA1                 \
-                +RSA:+CAMELLIA-256-CBC:+SHA1            \
-                +RSA:+AES-128-CBC:+SHA1                 \
-                +RSA:+CAMELLIA-128-CBC:+SHA1            \
-                +RSA:+3DES-CBC:+SHA1                    \
-                +RSA:+NULL:+MD5                         \
-                +RSA:+NULL:+SHA1                        \
-                "
-            O_CIPHERS="$O_CIPHERS               \
-                DHE-RSA-AES128-SHA              \
-                DHE-RSA-AES256-SHA              \
-                DHE-RSA-CAMELLIA128-SHA         \
-                DHE-RSA-CAMELLIA256-SHA         \
-                EDH-RSA-DES-CBC3-SHA            \
-                AES256-SHA                      \
-                CAMELLIA256-SHA                 \
-                AES128-SHA                      \
-                CAMELLIA128-SHA                 \
-                DES-CBC3-SHA                    \
-                NULL-MD5                        \
-                NULL-SHA                        \
-                "
             if [ `minor_ver "$MODE"` -gt 0 ]
             then
-                M_CIPHERS="$M_CIPHERS                       \
+                CIPHERS="$CIPHERS                           \
                     TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA      \
                     TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA      \
                     TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA     \
                     TLS-ECDHE-RSA-WITH-NULL-SHA             \
                     "
-                G_CIPHERS="$G_CIPHERS                       \
-                    +ECDHE-RSA:+AES-128-CBC:+SHA1           \
-                    +ECDHE-RSA:+AES-256-CBC:+SHA1           \
-                    +ECDHE-RSA:+3DES-CBC:+SHA1              \
-                    +ECDHE-RSA:+NULL:+SHA1                  \
-                    "
-                O_CIPHERS="$O_CIPHERS               \
-                    ECDHE-RSA-AES256-SHA            \
-                    ECDHE-RSA-AES128-SHA            \
-                    ECDHE-RSA-DES-CBC3-SHA          \
-                    ECDHE-RSA-NULL-SHA              \
-                    "
             fi
             if [ `minor_ver "$MODE"` -ge 3 ]
             then
-                M_CIPHERS="$M_CIPHERS                       \
+                CIPHERS="$CIPHERS                           \
                     TLS-RSA-WITH-AES-128-CBC-SHA256         \
                     TLS-DHE-RSA-WITH-AES-128-CBC-SHA256     \
                     TLS-RSA-WITH-AES-256-CBC-SHA256         \
@@ -367,62 +313,36 @@
                     TLS-DHE-RSA-WITH-AES-256-GCM-SHA384     \
                     TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256   \
                     TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384   \
-                    "
-                G_CIPHERS="$G_CIPHERS                       \
-                    +RSA:+AES-128-CBC:+SHA256               \
-                    +DHE-RSA:+AES-128-CBC:+SHA256           \
-                    +RSA:+AES-256-CBC:+SHA256               \
-                    +DHE-RSA:+AES-256-CBC:+SHA256           \
-                    +ECDHE-RSA:+AES-128-CBC:+SHA256         \
-                    +ECDHE-RSA:+AES-256-CBC:+SHA384         \
-                    +RSA:+AES-128-GCM:+AEAD                 \
-                    +RSA:+AES-256-GCM:+AEAD                 \
-                    +DHE-RSA:+AES-128-GCM:+AEAD             \
-                    +DHE-RSA:+AES-256-GCM:+AEAD             \
-                    +ECDHE-RSA:+AES-128-GCM:+AEAD           \
-                    +ECDHE-RSA:+AES-256-GCM:+AEAD           \
-                    "
-                O_CIPHERS="$O_CIPHERS           \
-                    NULL-SHA256                 \
-                    AES128-SHA256               \
-                    DHE-RSA-AES128-SHA256       \
-                    AES256-SHA256               \
-                    DHE-RSA-AES256-SHA256       \
-                    ECDHE-RSA-AES128-SHA256     \
-                    ECDHE-RSA-AES256-SHA384     \
-                    AES128-GCM-SHA256           \
-                    DHE-RSA-AES128-GCM-SHA256   \
-                    AES256-GCM-SHA384           \
-                    DHE-RSA-AES256-GCM-SHA384   \
-                    ECDHE-RSA-AES128-GCM-SHA256 \
-                    ECDHE-RSA-AES256-GCM-SHA384 \
+                    TLS-RSA-WITH-NULL-SHA256                \
                     "
             fi
             ;;
 
         "PSK")
-            M_CIPHERS="$M_CIPHERS                       \
+            CIPHERS="$CIPHERS                           \
                 TLS-PSK-WITH-3DES-EDE-CBC-SHA           \
                 TLS-PSK-WITH-AES-128-CBC-SHA            \
                 TLS-PSK-WITH-AES-256-CBC-SHA            \
                 "
-            G_CIPHERS="$G_CIPHERS                       \
-                +PSK:+3DES-CBC:+SHA1                    \
-                +PSK:+AES-128-CBC:+SHA1                 \
-                +PSK:+AES-256-CBC:+SHA1                 \
-                "
-            O_CIPHERS="$O_CIPHERS               \
-                PSK-3DES-EDE-CBC-SHA            \
-                PSK-AES128-CBC-SHA              \
-                PSK-AES256-CBC-SHA              \
-                "
             ;;
     esac
+
+    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
-# Each ciphersuite should appear two times, once with its OpenSSL name, once
-# with its Mbed TLS name.
+# 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.
 #
 # NOTE: for some reason RSA-PSK doesn't work with OpenSSL,
 # so RSA-PSK ciphersuites need to go in other sections, see
@@ -432,28 +352,23 @@
 # GnuTLS in 3.5.0 and the CI only has 3.4.x so far.
 add_openssl_ciphersuites()
 {
+    CIPHERS=""
     case $TYPE in
 
         "ECDSA")
             if [ `minor_ver "$MODE"` -gt 0 ]
             then
-                M_CIPHERS="$M_CIPHERS                       \
-                    TLS-ECDH-ECDSA-WITH-NULL-SHA            \
+                CIPHERS="$CIPHERS                           \
+                    TLS-ECDH-ECDSA-WITH-NULL-SHA       \
                     TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA    \
                     TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA     \
                     TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA     \
                     "
-                O_CIPHERS="$O_CIPHERS               \
-                    ECDH-ECDSA-NULL-SHA             \
-                    ECDH-ECDSA-DES-CBC3-SHA         \
-                    ECDH-ECDSA-AES128-SHA           \
-                    ECDH-ECDSA-AES256-SHA           \
-                    "
             fi
             if [ `minor_ver "$MODE"` -ge 3 ]
             then
-                M_CIPHERS="$M_CIPHERS                               \
-                    TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256          \
+                CIPHERS="$CIPHERS                           \
+                    TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256     \
                     TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384          \
                     TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256          \
                     TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384          \
@@ -461,31 +376,18 @@
                     TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256        \
                     TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256   \
                     "
-                O_CIPHERS="$O_CIPHERS               \
-                    ECDH-ECDSA-AES128-SHA256        \
-                    ECDH-ECDSA-AES256-SHA384        \
-                    ECDH-ECDSA-AES128-GCM-SHA256    \
-                    ECDH-ECDSA-AES256-GCM-SHA384    \
-                    ECDHE-ECDSA-ARIA256-GCM-SHA384  \
-                    ECDHE-ECDSA-ARIA128-GCM-SHA256  \
-                    ECDHE-ECDSA-CHACHA20-POLY1305   \
-                    "
             fi
             ;;
 
         "RSA")
-            M_CIPHERS="$M_CIPHERS                       \
-                TLS-RSA-WITH-DES-CBC-SHA                \
+            CIPHERS="$CIPHERS                           \
+                TLS-RSA-WITH-DES-CBC-SHA           \
                 TLS-DHE-RSA-WITH-DES-CBC-SHA            \
                 "
-            O_CIPHERS="$O_CIPHERS               \
-                DES-CBC-SHA                     \
-                EDH-RSA-DES-CBC-SHA             \
-                "
             if [ `minor_ver "$MODE"` -ge 3 ]
             then
-                M_CIPHERS="$M_CIPHERS                               \
-                    TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384          \
+                CIPHERS="$CIPHERS                           \
+                    TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384     \
                     TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384            \
                     TLS-RSA-WITH-ARIA-256-GCM-SHA384                \
                     TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256          \
@@ -494,24 +396,14 @@
                     TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256       \
                     TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256     \
                     "
-                O_CIPHERS="$O_CIPHERS               \
-                    ECDHE-ARIA256-GCM-SHA384        \
-                    DHE-RSA-ARIA256-GCM-SHA384      \
-                    ARIA256-GCM-SHA384              \
-                    ECDHE-ARIA128-GCM-SHA256        \
-                    DHE-RSA-ARIA128-GCM-SHA256      \
-                    ARIA128-GCM-SHA256              \
-                    DHE-RSA-CHACHA20-POLY1305       \
-                    ECDHE-RSA-CHACHA20-POLY1305     \
-                    "
             fi
             ;;
 
         "PSK")
             if [ `minor_ver "$MODE"` -ge 3 ]
             then
-                M_CIPHERS="$M_CIPHERS                               \
-                    TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384            \
+                CIPHERS="$CIPHERS                           \
+                    TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384       \
                     TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256            \
                     TLS-PSK-WITH-ARIA-256-GCM-SHA384                \
                     TLS-PSK-WITH-ARIA-128-GCM-SHA256                \
@@ -519,66 +411,47 @@
                     TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256     \
                     TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256       \
                     "
-                O_CIPHERS="$O_CIPHERS               \
-                    DHE-PSK-ARIA256-GCM-SHA384      \
-                    DHE-PSK-ARIA128-GCM-SHA256      \
-                    PSK-ARIA256-GCM-SHA384          \
-                    PSK-ARIA128-GCM-SHA256          \
-                    DHE-PSK-CHACHA20-POLY1305       \
-                    ECDHE-PSK-CHACHA20-POLY1305     \
-                    PSK-CHACHA20-POLY1305           \
-                    "
             fi
             ;;
     esac
+
+    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
-# Each ciphersuite should appear two times, once with its GnuTLS name, once
-# with its Mbed TLS name.
+# 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.
 add_gnutls_ciphersuites()
 {
+    CIPHERS=""
     case $TYPE in
 
         "ECDSA")
             if [ `minor_ver "$MODE"` -ge 3 ]
             then
-                M_CIPHERS="$M_CIPHERS                               \
-                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256    \
-                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384    \
-                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256    \
-                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384    \
-                    TLS-ECDHE-ECDSA-WITH-AES-128-CCM                \
-                    TLS-ECDHE-ECDSA-WITH-AES-256-CCM                \
-                    TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8              \
-                    TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8              \
-                   "
-                G_CIPHERS="$G_CIPHERS                               \
-                    +ECDHE-ECDSA:+CAMELLIA-128-CBC:+SHA256          \
-                    +ECDHE-ECDSA:+CAMELLIA-256-CBC:+SHA384          \
-                    +ECDHE-ECDSA:+CAMELLIA-128-GCM:+AEAD            \
-                    +ECDHE-ECDSA:+CAMELLIA-256-GCM:+AEAD            \
-                    +ECDHE-ECDSA:+AES-128-CCM:+AEAD                 \
-                    +ECDHE-ECDSA:+AES-256-CCM:+AEAD                 \
-                    +ECDHE-ECDSA:+AES-128-CCM-8:+AEAD               \
-                    +ECDHE-ECDSA:+AES-256-CCM-8:+AEAD               \
+                CIPHERS="$CIPHERS                           \
+                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256   \
+                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384        \
+                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256        \
+                    TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384        \
+                    TLS-ECDHE-ECDSA-WITH-AES-128-CCM                    \
+                    TLS-ECDHE-ECDSA-WITH-AES-256-CCM                    \
+                    TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8                  \
+                    TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8                  \
                    "
             fi
             ;;
 
         "RSA")
-            if [ `minor_ver "$MODE"` -gt 0 ]
-            then
-                M_CIPHERS="$M_CIPHERS                           \
-                    TLS-RSA-WITH-NULL-SHA256                    \
-                    "
-                G_CIPHERS="$G_CIPHERS                           \
-                    +RSA:+NULL:+SHA256                          \
-                    "
-            fi
             if [ `minor_ver "$MODE"` -ge 3 ]
             then
-                M_CIPHERS="$M_CIPHERS                           \
+                CIPHERS="$CIPHERS                               \
                     TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256  \
                     TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384  \
                     TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256        \
@@ -600,45 +473,18 @@
                     TLS-DHE-RSA-WITH-AES-128-CCM-8              \
                     TLS-DHE-RSA-WITH-AES-256-CCM-8              \
                     "
-                G_CIPHERS="$G_CIPHERS                           \
-                    +ECDHE-RSA:+CAMELLIA-128-CBC:+SHA256        \
-                    +ECDHE-RSA:+CAMELLIA-256-CBC:+SHA384        \
-                    +RSA:+CAMELLIA-128-CBC:+SHA256              \
-                    +RSA:+CAMELLIA-256-CBC:+SHA256              \
-                    +DHE-RSA:+CAMELLIA-128-CBC:+SHA256          \
-                    +DHE-RSA:+CAMELLIA-256-CBC:+SHA256          \
-                    +ECDHE-RSA:+CAMELLIA-128-GCM:+AEAD          \
-                    +ECDHE-RSA:+CAMELLIA-256-GCM:+AEAD          \
-                    +DHE-RSA:+CAMELLIA-128-GCM:+AEAD            \
-                    +DHE-RSA:+CAMELLIA-256-GCM:+AEAD            \
-                    +RSA:+CAMELLIA-128-GCM:+AEAD                \
-                    +RSA:+CAMELLIA-256-GCM:+AEAD                \
-                    +RSA:+AES-128-CCM:+AEAD                     \
-                    +RSA:+AES-256-CCM:+AEAD                     \
-                    +RSA:+AES-128-CCM-8:+AEAD                   \
-                    +RSA:+AES-256-CCM-8:+AEAD                   \
-                    +DHE-RSA:+AES-128-CCM:+AEAD                 \
-                    +DHE-RSA:+AES-256-CCM:+AEAD                 \
-                    +DHE-RSA:+AES-128-CCM-8:+AEAD               \
-                    +DHE-RSA:+AES-256-CCM-8:+AEAD               \
-                    "
             fi
             ;;
 
         "PSK")
-            M_CIPHERS="$M_CIPHERS                               \
-                TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA               \
-                TLS-DHE-PSK-WITH-AES-128-CBC-SHA                \
-                TLS-DHE-PSK-WITH-AES-256-CBC-SHA                \
-                "
-            G_CIPHERS="$G_CIPHERS                               \
-                +DHE-PSK:+3DES-CBC:+SHA1                        \
-                +DHE-PSK:+AES-128-CBC:+SHA1                     \
-                +DHE-PSK:+AES-256-CBC:+SHA1                     \
+            CIPHERS="$CIPHERS                                 \
+                TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA             \
+                TLS-DHE-PSK-WITH-AES-128-CBC-SHA              \
+                TLS-DHE-PSK-WITH-AES-256-CBC-SHA              \
                 "
             if [ `minor_ver "$MODE"` -gt 0 ]
             then
-                M_CIPHERS="$M_CIPHERS                           \
+                CIPHERS="$CIPHERS                               \
                     TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA          \
                     TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA          \
                     TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA         \
@@ -646,18 +492,10 @@
                     TLS-RSA-PSK-WITH-AES-256-CBC-SHA            \
                     TLS-RSA-PSK-WITH-AES-128-CBC-SHA            \
                     "
-                G_CIPHERS="$G_CIPHERS                           \
-                    +ECDHE-PSK:+3DES-CBC:+SHA1                  \
-                    +ECDHE-PSK:+AES-128-CBC:+SHA1               \
-                    +ECDHE-PSK:+AES-256-CBC:+SHA1               \
-                    +RSA-PSK:+3DES-CBC:+SHA1                    \
-                    +RSA-PSK:+AES-256-CBC:+SHA1                 \
-                    +RSA-PSK:+AES-128-CBC:+SHA1                 \
-                    "
             fi
             if [ `minor_ver "$MODE"` -ge 3 ]
             then
-                M_CIPHERS="$M_CIPHERS                           \
+                CIPHERS="$CIPHERS                               \
                     TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384       \
                     TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384  \
                     TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256       \
@@ -703,55 +541,15 @@
                     TLS-RSA-PSK-WITH-AES-256-GCM-SHA384         \
                     TLS-RSA-PSK-WITH-AES-128-GCM-SHA256         \
                     "
-                G_CIPHERS="$G_CIPHERS                           \
-                    +ECDHE-PSK:+AES-256-CBC:+SHA384             \
-                    +ECDHE-PSK:+CAMELLIA-256-CBC:+SHA384        \
-                    +ECDHE-PSK:+AES-128-CBC:+SHA256             \
-                    +ECDHE-PSK:+CAMELLIA-128-CBC:+SHA256        \
-                    +PSK:+AES-128-CBC:+SHA256                   \
-                    +PSK:+AES-256-CBC:+SHA384                   \
-                    +DHE-PSK:+AES-128-CBC:+SHA256               \
-                    +DHE-PSK:+AES-256-CBC:+SHA384               \
-                    +RSA-PSK:+AES-256-CBC:+SHA384               \
-                    +RSA-PSK:+AES-128-CBC:+SHA256               \
-                    +DHE-PSK:+CAMELLIA-128-CBC:+SHA256          \
-                    +DHE-PSK:+CAMELLIA-256-CBC:+SHA384          \
-                    +PSK:+CAMELLIA-128-CBC:+SHA256              \
-                    +PSK:+CAMELLIA-256-CBC:+SHA384              \
-                    +RSA-PSK:+CAMELLIA-256-CBC:+SHA384          \
-                    +RSA-PSK:+CAMELLIA-128-CBC:+SHA256          \
-                    +PSK:+AES-128-GCM:+AEAD                     \
-                    +PSK:+AES-256-GCM:+AEAD                     \
-                    +DHE-PSK:+AES-128-GCM:+AEAD                 \
-                    +DHE-PSK:+AES-256-GCM:+AEAD                 \
-                    +PSK:+AES-128-CCM:+AEAD                     \
-                    +PSK:+AES-256-CCM:+AEAD                     \
-                    +DHE-PSK:+AES-128-CCM:+AEAD                 \
-                    +DHE-PSK:+AES-256-CCM:+AEAD                 \
-                    +PSK:+AES-128-CCM-8:+AEAD                   \
-                    +PSK:+AES-256-CCM-8:+AEAD                   \
-                    +DHE-PSK:+AES-128-CCM-8:+AEAD               \
-                    +DHE-PSK:+AES-256-CCM-8:+AEAD               \
-                    +RSA-PSK:+CAMELLIA-128-GCM:+AEAD            \
-                    +RSA-PSK:+CAMELLIA-256-GCM:+AEAD            \
-                    +PSK:+CAMELLIA-128-GCM:+AEAD                \
-                    +PSK:+CAMELLIA-256-GCM:+AEAD                \
-                    +DHE-PSK:+CAMELLIA-128-GCM:+AEAD            \
-                    +DHE-PSK:+CAMELLIA-256-GCM:+AEAD            \
-                    +RSA-PSK:+AES-256-GCM:+AEAD                 \
-                    +RSA-PSK:+AES-128-GCM:+AEAD                 \
-                    +ECDHE-PSK:+NULL:+SHA384                    \
-                    +ECDHE-PSK:+NULL:+SHA256                    \
-                    +PSK:+NULL:+SHA256                          \
-                    +PSK:+NULL:+SHA384                          \
-                    +DHE-PSK:+NULL:+SHA256                      \
-                    +DHE-PSK:+NULL:+SHA384                      \
-                    +RSA-PSK:+NULL:+SHA256                      \
-                    +RSA-PSK:+NULL:+SHA384                      \
-                    "
             fi
             ;;
     esac
+
+    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
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index a5562cc..f30795c 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -2770,12 +2770,15 @@
     tests/scripts/check-python-files.sh
 }
 
-component_check_generate_test_code () {
-    msg "uint test: generate_test_code.py"
+component_check_test_helpers () {
+    msg "unit test: generate_test_code.py"
     # unittest writes out mundane stuff like number or tests run on stderr.
     # Our convention is to reserve stderr for actual errors, and write
     # harmless info on stdout so it can be suppress with --quiet.
     ./tests/scripts/test_generate_test_code.py 2>&1
+
+    msg "unit test: translate_ciphers.py"
+    python3 -m unittest tests/scripts/translate_ciphers.py 2>&1
 }
 
 ################################################################
diff --git a/tests/scripts/translate_ciphers.py b/tests/scripts/translate_ciphers.py
new file mode 100755
index 0000000..d5f847f
--- /dev/null
+++ b/tests/scripts/translate_ciphers.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+
+# translate_ciphers.py
+#
+# Copyright The Mbed TLS Contributors
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Translate ciphersuite names in Mbed TLS format to OpenSSL and GNUTLS
+standards.
+
+To test the translation functions run:
+python3 -m unittest translate_cipher.py
+"""
+
+import re
+import argparse
+import unittest
+
+class TestTranslateCiphers(unittest.TestCase):
+    """
+    Ensure translate_ciphers.py translates and formats ciphersuite names
+    correctly
+    """
+    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
+        """
+        ciphers = [
+            ("TLS-ECDHE-ECDSA-WITH-NULL-SHA",
+             "+ECDHE-ECDSA:+NULL:+SHA1",
+             "ECDHE-ECDSA-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",
+             "+DHE-RSA:+3DES-CBC:+SHA1",
+             "EDH-RSA-DES-CBC3-SHA"),
+            ("TLS-RSA-WITH-AES-256-CBC-SHA",
+             "+RSA:+AES-256-CBC:+SHA1",
+             "AES256-SHA"),
+            ("TLS-PSK-WITH-3DES-EDE-CBC-SHA",
+             "+PSK:+3DES-CBC:+SHA1",
+             "PSK-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:+AES-128-CCM:+AEAD",
+             None),
+            ("TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384",
+             None,
+             "ECDHE-ARIA256-GCM-SHA384"),
+        ]
+
+        for m, g_exp, o_exp in ciphers:
+
+            if g_exp is not None:
+                g = translate_gnutls(m)
+                self.assertEqual(g, g_exp)
+
+            if o_exp is not None:
+                o = translate_ossl(m)
+                self.assertEqual(o, o_exp)
+
+def translate_gnutls(m_cipher):
+    """
+    Translate m_cipher from Mbed TLS 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", "")
+
+    # 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"
+
+    # 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"
+
+    # Replace the last "-" with ":+"
+    else:
+        index = m_cipher.rindex("-")
+        m_cipher = m_cipher[:index] + ":+" + m_cipher[index+1:]
+
+    return m_cipher
+
+def translate_ossl(m_cipher):
+    """
+    Translate m_cipher from Mbed TLS ciphersuite naming convention
+    and return the OpenSSL naming convention
+    """
+
+    m_cipher = re.sub(r'^TLS-', '', m_cipher)
+    m_cipher = m_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")
+
+    # Remove "RSA" if it is at the beginning
+    m_cipher = re.sub(r'^RSA-', r'', m_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")
+
+        # Remove "CBC" if it is not prefixed by DES
+        m_cipher = re.sub(r'(?<!DES-)CBC-', r'', m_cipher)
+
+    # ECDHE-RSA-ARIA does not exist in OpenSSL
+    m_cipher = m_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 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")
+
+    return m_cipher
+
+def format_ciphersuite_names(mode, names):
+    t = {"g": translate_gnutls, "o": translate_ossl}[mode]
+    return " ".join(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('names', metavar='NAMES', nargs='+')
+    ARGS = PARSER.parse_args()
+    main(ARGS.target, ARGS.names)