Add identifiers and API for configuration of TLS 1.3 key exchanges

Signed-off-by: Hanno Becker <hanno.becker@arm.com>
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index f49bf2d..029fa42 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -170,6 +170,30 @@
 #define MBEDTLS_ERR_SSL_BAD_CONFIG                        -0x5E80
 
 /*
+ * TLS 1.3 Key Exchange Modes
+ *
+ * Mbed TLS internal identifiers for use with the SSL configuration API
+ * mbedtls_ssl_conf_tls13_key_exchange_modes().
+ */
+
+#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_NONE           0
+#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK            ( 1u << 0 )
+#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL  ( 1u << 1 )
+#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL      ( 1u << 2 )
+
+/* Convenience macros for sets of key exchanges. */
+#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL                         \
+    ( MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK              |            \
+      MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL    |            \
+      MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL )
+#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL                     \
+    ( MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK              |            \
+      MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL    )
+#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL_ALL               \
+    ( MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL        |            \
+      MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL    )
+
+/*
  * Various constants
  */
 
@@ -1069,6 +1093,11 @@
     /** Allowed ciphersuites for (D)TLS 1.2 (0-terminated)                  */
     const int *MBEDTLS_PRIVATE(ciphersuite_list);
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    /** Allowed TLS 1.3 key exchange modes.                                 */
+    int MBEDTLS_PRIVATE(tls13_kex_modes);
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
     /** Callback for printing debug output                                  */
     void (*MBEDTLS_PRIVATE(f_dbg))(void *, int, const char *, int, const char *);
     void *MBEDTLS_PRIVATE(p_dbg);                    /*!< context for the debug function     */
@@ -2561,6 +2590,53 @@
 void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
                                     const int *ciphersuites );
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+/**
+ * \brief Set the supported key exchange modes for TLS 1.3 connections.
+ *
+ *        In contrast to TLS 1.2, the ciphersuite concept in TLS 1.3 does not
+ *        include the choice of key exchange mechanism. It is therefore not
+ *        covered by the API mbedtls_ssl_conf_ciphersuites(). See the
+ *        documentation of mbedtls_ssl_conf_ciphersuites() for more
+ *        information on the ciphersuite concept in TLS 1.2 and TLS 1.3.
+ *
+ *        The present function is specific to TLS 1.3 and allows users to
+ *        configure the set of supported key exchange mechanisms in TLS 1.3.
+ *
+ * \param conf       The SSL configuration the change should apply to.
+ * \param kex_modes  A bitwise combination of one or more of the following:
+ *                   - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK
+ *                     This flag enables pure-PSK key exchanges.
+ *                   - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL
+ *                     This flag enables combined PSK-ephemeral key exchanges.
+ *                   - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL
+ *                     This flag enables pure-ephemeral key exchanges.
+ *                   For convenience, the following pre-defined macros are
+ *                   available for combinations of the above:
+ *                   - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL
+ *                     Includes all of pure-PSK, PSK-ephemeral and pure-ephemeral.
+ *                   - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL
+ *                     Includes both pure-PSK and combined PSK-ephemeral
+ *                     key exchanges, but excludes pure-ephemeral key exchanges.
+ *                   - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL_ALL
+ *                     Includes both pure-ephemeral and combined PSK-ephemeral
+ *                     key exchanges.
+ *
+ * \note  If a PSK-based key exchange mode shall be supported, applications
+ *        must also use the APIs mbedtls_ssl_conf_psk() or
+ *        mbedtls_ssl_conf_psk_cb() or mbedtls_ssl_conf_psk_opaque()
+ *        to configure the PSKs to be used.
+ *
+ * \note  If an ECDHE-based key exchange mode shall be supported,
+ *        server-side applications must also provide a certificate via
+ *        mbedtls_ssl_conf_own_cert().
+ *
+ */
+
+void mbedtls_ssl_conf_tls13_key_exchange_modes( mbedtls_ssl_config* conf,
+                                                const int kex_modes );
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
 #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
 #define MBEDTLS_SSL_UNEXPECTED_CID_IGNORE 0
 #define MBEDTLS_SSL_UNEXPECTED_CID_FAIL   1
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 97bb7b6..4933980 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3548,6 +3548,14 @@
     conf->ciphersuite_list = ciphersuites;
 }
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+void mbedtls_ssl_conf_tls13_key_exchange_modes( mbedtls_ssl_config* conf,
+                                                const int kex_modes )
+{
+    conf->tls13_kex_modes = kex_modes;
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf,
                                     const mbedtls_x509_crt_profile *profile )
@@ -6353,6 +6361,13 @@
     }
 #endif
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+    /*
+     * Allow all TLS 1.3 key exchange modes by default.
+     */
+    conf->tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
     /*
      * Preset-specific defaults
      */