Add FFDH definitions and translation functions

Signed-off-by: Przemek Stekiel <przemyslaw.stekiel@mobica.com>

Signed-off-by: Przemek Stekiel <przemyslaw.stekiel@mobica.com>
diff --git a/include/mbedtls/dhm.h b/include/mbedtls/dhm.h
index 6ffe681..b7c3256 100644
--- a/include/mbedtls/dhm.h
+++ b/include/mbedtls/dhm.h
@@ -66,6 +66,7 @@
 
 #include "mbedtls/build_info.h"
 #include "mbedtls/bignum.h"
+#include <string.h>
 
 /*
  * DHM Error codes
@@ -91,6 +92,20 @@
 /** Setting the modulus and generator failed. */
 #define MBEDTLS_ERR_DHM_SET_GROUP_FAILED                  -0x3580
 
+/* Finite Field Groups (DHE) */
+#define MBEDTLS_DHM_GROUP_FFDHE2048     0x0100
+#define MBEDTLS_DHM_GROUP_FFDHE3072     0x0101
+#define MBEDTLS_DHM_GROUP_FFDHE4096     0x0102
+#define MBEDTLS_DHM_GROUP_FFDHE6144     0x0103
+#define MBEDTLS_DHM_GROUP_FFDHE8192     0x0104
+
+/* Finite Field Group Names (DHE) */
+#define MBEDTLS_DHM_GROUP_NAME_FFDHE2048     "ffdhe2048"
+#define MBEDTLS_DHM_GROUP_NAME_FFDHE3072     "ffdhe3072"
+#define MBEDTLS_DHM_GROUP_NAME_FFDHE4096     "ffdhe4096"
+#define MBEDTLS_DHM_GROUP_NAME_FFDHE6144     "ffdhe6144"
+#define MBEDTLS_DHM_GROUP_NAME_FFDHE8192     "ffdhe8192"
+
 /** Which parameter to access in mbedtls_dhm_get_value(). */
 typedef enum {
     MBEDTLS_DHM_PARAM_P,  /*!<  The prime modulus. */
@@ -377,6 +392,55 @@
 #endif /* MBEDTLS_FS_IO */
 #endif /* MBEDTLS_ASN1_PARSE_C */
 
+static inline uint16_t mbedtls_ssl_ffdh_group_from_name(const char *name)
+{
+    if (strcmp(name, MBEDTLS_DHM_GROUP_NAME_FFDHE2048) == 0) {
+        return MBEDTLS_DHM_GROUP_FFDHE2048;
+    } else if (strcmp(name, MBEDTLS_DHM_GROUP_NAME_FFDHE3072) == 0) {
+        return MBEDTLS_DHM_GROUP_FFDHE3072;
+    } else if (strcmp(name, MBEDTLS_DHM_GROUP_NAME_FFDHE4096) == 0) {
+        return MBEDTLS_DHM_GROUP_FFDHE4096;
+    } else if (strcmp(name, MBEDTLS_DHM_GROUP_NAME_FFDHE6144) == 0) {
+        return MBEDTLS_DHM_GROUP_FFDHE6144;
+    } else if (strcmp(name, MBEDTLS_DHM_GROUP_NAME_FFDHE8192) == 0) {
+        return MBEDTLS_DHM_GROUP_FFDHE8192;
+    }
+    return 0;
+}
+
+static inline const char *mbedtls_ssl_ffdh_name_from_group(uint16_t group)
+{
+    switch (group) {
+        case MBEDTLS_DHM_GROUP_FFDHE2048:
+            return MBEDTLS_DHM_GROUP_NAME_FFDHE2048;
+        case MBEDTLS_DHM_GROUP_FFDHE3072:
+            return MBEDTLS_DHM_GROUP_NAME_FFDHE3072;
+        case MBEDTLS_DHM_GROUP_FFDHE4096:
+            return MBEDTLS_DHM_GROUP_NAME_FFDHE4096;
+        case MBEDTLS_DHM_GROUP_FFDHE6144:
+            return MBEDTLS_DHM_GROUP_NAME_FFDHE6144;
+        case MBEDTLS_DHM_GROUP_FFDHE8192:
+            return MBEDTLS_DHM_GROUP_NAME_FFDHE8192;
+        default:
+            return NULL;
+    }
+    return NULL;
+}
+
+static inline uint16_t *mbedtls_ssl_ffdh_supported_groups(void)
+{
+    static uint16_t ffdh_groups[] = {
+        MBEDTLS_DHM_GROUP_FFDHE2048,
+        MBEDTLS_DHM_GROUP_FFDHE3072,
+        MBEDTLS_DHM_GROUP_FFDHE4096,
+        MBEDTLS_DHM_GROUP_FFDHE6144,
+        MBEDTLS_DHM_GROUP_FFDHE8192,
+        0
+    };
+
+    return ffdh_groups;
+}
+
 #if defined(MBEDTLS_SELF_TEST)
 
 /**
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index 64c2435..e67acdf 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -38,6 +38,7 @@
 #include "mbedtls/pk.h"
 #include "mbedtls/oid.h"
 #include "mbedtls/error.h"
+#include "mbedtls/ssl.h"
 
 #include <string.h>
 
@@ -276,6 +277,33 @@
 #define MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH \
     PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
 
+#define MBEDTLS_PSA_MAX_FFDH_PUBKEY_LENGTH \
+    PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS)
+
+static inline psa_key_type_t mbedtls_psa_parse_tls_ffdh_group(
+    uint16_t tls_ecc_grp_reg_id, size_t *bits)
+{
+    switch (tls_ecc_grp_reg_id) {
+        case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE2048:
+            *bits = 2048;
+            return PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919);
+        case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE3072:
+            *bits = 3072;
+            return PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919);
+        case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE4096:
+            *bits = 4096;
+            return PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919);
+        case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE6144:
+            *bits = 6144;
+            return PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919);
+        case MBEDTLS_SSL_IANA_TLS_GROUP_FFDHE8192:
+            *bits = 8192;
+            return PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919);
+        default:
+            return 0;
+    }
+}
+
 /* Expose whatever RNG the PSA subsystem uses to applications using the
  * mbedtls_xxx API. The declarations and definitions here need to be
  * consistent with the implementation in library/psa_crypto_random_impl.h.
diff --git a/library/ssl_client.c b/library/ssl_client.c
index 7fa3737..163d0a0 100644
--- a/library/ssl_client.c
+++ b/library/ssl_client.c
@@ -307,7 +307,7 @@
             p += 2;
             MBEDTLS_SSL_DEBUG_MSG(3, ("NamedGroup: %s ( %x )",
                                       ffdh_group, *group_list));
-        
+        }
     }
 
     /* Length of named_group_list */
@@ -336,7 +336,6 @@
 
     return 0;
 }
-
 #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
 
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 17149c5..e3bc776 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -756,15 +756,19 @@
     mbedtls_ecdh_context ecdh_ctx;              /*!<  ECDH key exchange       */
 #endif /* MBEDTLS_ECDH_C && !MBEDTLS_USE_PSA_CRYPTO */
 
-#if defined(PSA_WANT_ALG_ECDH) && \
+#if (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) && \
     (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
     psa_key_type_t ecdh_psa_type;
     size_t ecdh_bits;
     mbedtls_svc_key_id_t ecdh_psa_privkey;
     uint8_t ecdh_psa_privkey_is_external;
+#if defined(PSA_WANT_ALG_FFDH)
+    unsigned char ecdh_psa_peerkey[MBEDTLS_PSA_MAX_FFDH_PUBKEY_LENGTH];
+#else
     unsigned char ecdh_psa_peerkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
+#endif
     size_t ecdh_psa_peerkey_len;
-#endif /* PSA_WANT_ALG_ECDH &&
+#endif /* (PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH) &&
           (MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3) */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -2122,6 +2126,13 @@
     size_t *out_len);
 #endif /* PSA_WANT_ALG_ECDH */
 
+int mbedtls_ssl_tls13_generate_and_write_dhe_key_exchange(
+    mbedtls_ssl_context *ssl,
+    uint16_t named_group,
+    unsigned char *buf,
+    unsigned char *end,
+    size_t *out_len);
+
 #if defined(MBEDTLS_SSL_EARLY_DATA)
 int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
                                            unsigned char *buf,
@@ -2245,9 +2256,15 @@
             return 1;
         }
     }
-#else
-    ((void) named_group);
-#endif /* PSA_WANT_ALG_ECDH */
+#endif
+#if defined(PSA_WANT_ALG_FFDH)
+    if (mbedtls_ssl_tls13_named_group_is_dhe(named_group)) {
+        return 1;
+    }
+#endif
+#if !defined(PSA_WANT_ALG_ECDH) && !defined(PSA_WANT_ALG_FFDH)
+    (void) named_group;
+#endif
     return 0;
 }