tls13: add ecdh_read_public

Signed-off-by: Jerry Yu <jerry.h.yu@arm.com>
diff --git a/library/ecdh.c b/library/ecdh.c
index b72bd1f..b1d7c2a 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -31,6 +31,7 @@
 #include "mbedtls/ecdh.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
+#include "ssl_misc.h"
 
 #include "ecdh_misc.h"
 
@@ -690,6 +691,55 @@
     return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
 }
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+static int ecdh_read_tls13_public_internal( mbedtls_ecdh_context_mbed *ctx,
+                                            const unsigned char *buf,
+                                            size_t blen )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    const unsigned char *p = buf;
+
+    if( ( ret = mbedtls_ecp_tls13_read_point( &ctx->grp, &ctx->Qp, &p,
+                                              blen ) ) != 0 )
+        return( ret );
+
+    if( (size_t)( p - buf ) != blen )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    return( 0 );
+}
+
+/*
+ * Parse and import the client's TLS 1.3 public value
+ */
+int mbedtls_ecdh_tls13_read_public( mbedtls_ecdh_context *ctx,
+                                    const unsigned char *buf, size_t blen )
+{
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_read_tls13_public_internal( ctx, buf, blen ) );
+#else
+    switch( ctx->var )
+    {
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+        case MBEDTLS_ECDH_VARIANT_EVEREST:
+            return( mbedtls_everest_read_public( &ctx->ctx.everest_ecdh,
+                                                 buf, blen ) );
+#endif
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_read_tls13_public_internal( &ctx->ctx.mbed_ecdh,
+                                                     buf, blen ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
 /*
  * Derive and export the shared secret
  */
diff --git a/library/ecp.c b/library/ecp.c
index 0212069..a49cc45 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -79,6 +79,7 @@
 
 #include "bn_mul.h"
 #include "ecp_invasive.h"
+#include "ssl_misc.h"
 
 #include <string.h>
 
@@ -1051,6 +1052,39 @@
     return( ret );
 }
 
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+int mbedtls_ecp_tls13_read_point( const mbedtls_ecp_group *grp,
+                                  mbedtls_ecp_point *pt,
+                                  const unsigned char **buf, size_t buf_len )
+{
+    unsigned char data_len;
+    const unsigned char *buf_start;
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( pt  != NULL );
+    ECP_VALIDATE_RET( buf != NULL );
+    ECP_VALIDATE_RET( *buf != NULL );
+
+    if( buf_len < 3 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    data_len = ( *( *buf ) << 8 ) | *( *buf+1 );
+    *buf += 2;
+
+    if( data_len < 1 || data_len > buf_len - 2 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    /*
+     * Save buffer start for read_binary and update buf
+     */
+    buf_start = *buf;
+    *buf += data_len;
+
+    return( mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ) );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
 /*
  * Fast mod-p functions expect their argument to be in the 0..p^2 range.
  *
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 4ccfbc5..6206c6f 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -1538,6 +1538,24 @@
                                                 size_t dst_len,
                                                 size_t *olen );
 
+#if defined(MBEDTLS_ECDH_C)
+/*
+ * TLS 1.3 version of mbedtls_ecdh_read_public in ecdh.h
+ */
+int mbedtls_ecdh_tls13_read_public( mbedtls_ecdh_context *ctx,
+                                    const unsigned char *buf,
+                                    size_t blen );
+#endif /* MBEDTLS_ECDH_C */
+
+#if defined(MBEDTLS_ECP_C)
+/*
+ * TLS 1.3 version of mbedtls_ecp_tls_read_point in ecp.h
+ */
+int mbedtls_ecp_tls13_read_point( const mbedtls_ecp_group *grp,
+                                  mbedtls_ecp_point *pt,
+                                  const unsigned char **buf, size_t len );
+#endif /* MBEDTLS_ECP_C */
+
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
 /*
  * Write TLS 1.3 Signature Algorithm extension