Cleanup client_hello body.

cleanup `ssl_tls13_write_client_hello_body`, fix comments issues.
And move ciphersuites to separate function

Signed-off-by: Jerry Yu <jerry.h.yu@arm.com>
diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c
index f30d408..f9cfff5 100644
--- a/library/ssl_tls13_client.c
+++ b/library/ssl_tls13_client.c
@@ -115,8 +115,79 @@
 
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
-/* Functions for writing ClientHello message */
+/* Write ciphersuites
+ * CipherSuite cipher_suites<2..2^16-2>;
+ */
+static int ssl_tls13_write_client_hello_ciphersuites(
+            mbedtls_ssl_context *ssl,
+            unsigned char *buf,
+            unsigned char *end,
+            size_t *olen )
+{
+    /* Ciphersuite-related variables */
+    const int *ciphersuites;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+    /*  ciphersuite_start points to the start of
+        the ciphersuite list, i.e. to the length field*/
+    unsigned char *ciphersuite_start, *ciphersuite_iter;
+    size_t buf_len;
 
+    *olen = 0 ;
+
+    /*
+     * Ciphersuite list
+     *
+     * This is a list of the symmetric cipher options supported by
+     * the client, specifically the record protection algorithm
+     * ( including secret key length ) and a hash to be used with
+     * HKDF, in descending order of client preference.
+     */
+    ciphersuites = ssl->conf->ciphersuite_list;
+
+    /* Check available spaces for ciphersuite */
+    MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 2 );
+
+    /* Write ciphersuites */
+    ciphersuite_start = buf + 2;
+    ciphersuite_iter  = ciphersuite_start;
+
+    for ( size_t i = 0; ciphersuites[i] != 0; i++ )
+    {
+        ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
+
+        if( ciphersuite_info == NULL )
+            continue;
+
+        if( ciphersuite_info->min_minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 ||
+            ciphersuite_info->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 )
+            continue;
+
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x, %s",
+                                    (unsigned int) ciphersuites[i],
+                                    ciphersuite_info->name ) );
+
+        /* Check for available spaces */
+        MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 2 );
+
+        MBEDTLS_PUT_UINT16_BE( ciphersuites[i], ciphersuite_iter, 0);
+        ciphersuite_iter += 2;
+
+    }
+
+    buf_len = ciphersuite_iter - ciphersuite_start;
+
+    /* write ciphersuite buf length */
+    MBEDTLS_PUT_UINT16_BE( buf_len, buf, 0 );
+
+
+    MBEDTLS_SSL_DEBUG_MSG( 3,
+                           ( "client hello, got %" MBEDTLS_PRINTF_SIZET " ciphersuites",
+                             buf_len/2 ) );
+
+    return( 0 );
+}
+
+/* Functions for writing ClientHello message */
 static int ssl_tls13_write_client_hello_body( mbedtls_ssl_context *ssl,
                                               unsigned char *buf,
                                               size_t buflen,
@@ -139,13 +210,7 @@
     unsigned char *start = buf;
     unsigned char *end = buf + buflen;
 
-    /* Ciphersuite-related variables */
-    const int *ciphersuites;
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
-    /*  ciphersuite_start points to the start of
-        the ciphersuite list, i.e. to the length field*/
-    unsigned char *ciphersuite_start;
-    size_t ciphersuite_count;
+    *len_with_binders = 0;
 
     /* Keeping track of the included extensions */
     ssl->handshake->extensions_present = MBEDTLS_SSL_EXT_NONE;
@@ -169,7 +234,9 @@
     ssl->major_ver = ssl->conf->min_major_ver;
     ssl->minor_ver = ssl->conf->min_minor_ver;
 
-    /* For TLS 1.3 we use the legacy version number {0x03, 0x03}
+    /* Write legacy_version
+     *    ProtocolVersion legacy_version = 0x0303;    // TLS v1.2
+     * For TLS 1.3 we use the legacy version number {0x03, 0x03}
      *  instead of the true version number.
      *
      *  For DTLS 1.3 we use the legacy version number
@@ -180,16 +247,16 @@
     MBEDTLS_SSL_CHK_BUF_PTR( buf, end, CLIENT_HELLO_LEGACY_VERSION_LEN );
     MBEDTLS_PUT_UINT16_BE( 0x0303, buf, 0);
     buf += CLIENT_HELLO_LEGACY_VERSION_LEN;
-    buflen -= CLIENT_HELLO_LEGACY_VERSION_LEN;
 
-    /* Write random bytes */
+    /* Write random bytes
+            Random random
+    */
     MBEDTLS_SSL_CHK_BUF_PTR( buf, end, CLIENT_HELLO_RANDOM_LEN );
     memcpy( buf, ssl->handshake->randbytes, CLIENT_HELLO_RANDOM_LEN );
     MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes",
                            buf, CLIENT_HELLO_RANDOM_LEN );
 
     buf += CLIENT_HELLO_RANDOM_LEN;
-    buflen -= CLIENT_HELLO_RANDOM_LEN;
 
     /* Versions of TLS before TLS 1.3 supported a
      * "session resumption" feature which has been merged with pre-shared
@@ -203,74 +270,14 @@
      * ossification ). Otherwise, it MUST be set as a zero-length vector
      * ( i.e., a zero-valued single byte length field ).
      */
-    if( buflen < 1 )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small to hold ClientHello" ) );
-        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-    }
-
+    MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 1 );
     *buf++ = 0; /* session id length set to zero */
-    buflen -= 1;
 
-    /*
-     * Ciphersuite list
-     *
-     * This is a list of the symmetric cipher options supported by
-     * the client, specifically the record protection algorithm
-     * ( including secret key length ) and a hash to be used with
-     * HKDF, in descending order of client preference.
-     */
-    ciphersuites = ssl->conf->ciphersuite_list;
-
-    if( buflen < 2 /* for ciphersuite list length */ )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small to hold ClientHello" ) );
-        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-    }
-
-    /* Skip writing ciphersuite length for now */
-    ciphersuite_count = 0;
-    ciphersuite_start = buf;
-    buf += 2;
-    buflen -= 2;
-
-    for ( size_t i = 0; ciphersuites[i] != 0; i++ )
-    {
-        ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
-
-        if( ciphersuite_info == NULL )
-            continue;
-
-        if( ciphersuite_info->min_minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 ||
-            ciphersuite_info->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 )
-            continue;
-
-        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x, %s",
-                                    (unsigned int) ciphersuites[i],
-                                    ciphersuite_info->name ) );
-
-        ciphersuite_count++;
-
-        if( buflen < 2 /* for ciphersuite list length */ )
-        {
-            MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small to hold ClientHello" ) );
-            return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-        }
-
-        MBEDTLS_PUT_UINT16_BE( ciphersuites[i], buf, 0);
-
-        buf += 2;
-        buflen -= 2;
-
-    }
-
-    /* write ciphersuite length now */
-    MBEDTLS_PUT_UINT16_BE( ciphersuite_count*2, ciphersuite_start, 0 );
-    ciphersuite_start += 2;
-
-    MBEDTLS_SSL_DEBUG_MSG( 3,
-                           ( "client hello, got %" MBEDTLS_PRINTF_SIZET " ciphersuites",
-                             ciphersuite_count ) );
+    /* Write ciphersuites */
+    ret = ssl_tls13_write_client_hello_ciphersuites( ssl, buf, end, &cur_ext_len );
+    if( ret != 0)
+        return( ret );
+    buf += cur_ext_len;
 
     /* For every TLS 1.3 ClientHello, this vector MUST contain exactly
      * one byte set to zero, which corresponds to the 'null' compression
@@ -278,20 +285,13 @@
      *
      * For cTLS this field is elided.
      */
-    if( buflen < 2 /* for ciphersuite list length */ )
-    {
-        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small to hold ClientHello" ) );
-        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-    }
-
+    MBEDTLS_SSL_CHK_BUF_PTR( buf, end, 2 );
     *buf++ = 1;
     *buf++ = MBEDTLS_SSL_COMPRESS_NULL;
 
-    buflen -= 2;
 
     /* First write extensions, then the total length */
     extension_start = buf;
-    total_ext_len = 0;
     buf += 2;
 
     /* Supported Versions Extension is mandatory with TLS 1.3.
@@ -302,7 +302,6 @@
     ret = ssl_tls13_write_supported_versions_ext( ssl, buf, end, &cur_ext_len );
     if( ret != 0 )
         return( ret );
-    total_ext_len += cur_ext_len;
     buf += cur_ext_len;
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
@@ -312,8 +311,6 @@
     ret = ssl_tls13_write_supported_groups_ext( ssl, buf, end, &cur_ext_len );
     if( ret != 0 )
         return( ret );
-
-    total_ext_len += cur_ext_len;
     buf += cur_ext_len;
 
     /* The supported_signature_algorithms extension is REQUIRED for
@@ -321,8 +318,6 @@
     ret = mbedtls_ssl_tls13_write_sig_alg_ext( ssl, buf, end, &cur_ext_len );
     if( ret != 0 )
         return( ret );
-
-    total_ext_len += cur_ext_len;
     buf += cur_ext_len;
 
     /* We need to send the key shares under three conditions:
@@ -338,13 +333,13 @@
     ret = ssl_tls13_write_key_shares_ext( ssl, buf, end, &cur_ext_len );
     if( ret != 0 )
         return( ret );
-
-    total_ext_len += cur_ext_len;
     buf += cur_ext_len;
+
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
 
     /* Add more extensions here */
 
+    total_ext_len = buf - extension_start - 2;
     MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %" MBEDTLS_PRINTF_SIZET ,
                                 total_ext_len ) );
 
@@ -354,7 +349,7 @@
     MBEDTLS_PUT_UINT16_BE( total_ext_len, extension_start, 0 );
     extension_start += 2;
 
-    *len_with_binders = ( extension_start + total_ext_len ) - start;
+    *len_with_binders = buf - start;
     return( 0 );
 }
 
@@ -390,9 +385,6 @@
  *
  * Structure of this message:
  *
- *    uint16 ProtocolVersion;
- *    opaque Random[32];
- *    uint8 CipherSuite[2];     // Cryptographic suite selector
  *    struct {
  *        ProtocolVersion legacy_version = 0x0303;    // TLS v1.2
  *        Random random;