Add hello retry request in client side

Signed-off-by: XiaokangQian <xiaokang.qian@arm.com>
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 5e8b60b..759adec 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3400,8 +3400,8 @@
  * If partial is non-zero, keep data in the input buffer and client ID.
  * (Use when a DTLS client reconnects from the same port.)
  */
-static void ssl_session_reset_msg_layer( mbedtls_ssl_context *ssl,
-                                         int partial )
+void mbedtls_ssl_tls13_session_reset_msg_layer( mbedtls_ssl_context *ssl,
+                                                int partial )
 {
 #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
     size_t in_buf_len = ssl->in_buf_len;
@@ -3467,7 +3467,7 @@
 
     ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
 
-    ssl_session_reset_msg_layer( ssl, partial );
+    mbedtls_ssl_tls13_session_reset_msg_layer( ssl, partial );
 
     /* Reset renegotiation state */
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -7384,6 +7384,7 @@
     }
     return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
 }
+
 #endif /* !MBEDTLS_USE_PSA_CRYPTO */
 
 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) || \
@@ -7614,5 +7615,97 @@
     return( 0 );
 }
 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+static int ssl_hash_transcript_core( mbedtls_ssl_context *ssl,
+                                     mbedtls_md_type_t md,
+                                     unsigned char *transcript,
+                                     size_t len,
+                                     size_t *olen )
+{
+    int ret;
+    size_t hash_size;
+
+    if( len < 4 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    ret = mbedtls_ssl_get_handshake_transcript( ssl, md,
+                                          transcript + 4,
+                                          len - 4,
+                                          &hash_size );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 4, "mbedtls_ssl_get_handshake_transcript", ret );
+        return( ret );
+    }
+
+    transcript[0] = MBEDTLS_SSL_HS_MESSAGE_HASH;
+    transcript[1] = 0;
+    transcript[2] = 0;
+    transcript[3] = (unsigned char) hash_size;
+
+    *olen = 4 + hash_size;
+    return( 0 );
+}
+
+/* Reset SSL context and update hash for handling HRR.
+ *
+ * Replace Transcript-Hash(X) by
+ * Transcript-Hash( message_hash     ||
+ *                 00 00 Hash.length ||
+ *                 X )
+ * A few states of the handshake are preserved, including:
+ *   - session ID
+ *   - session ticket
+ *   - negotiated ciphersuite
+ */
+int mbedtls_ssl_reset_transcript_for_hrr( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    unsigned char hash_transcript[ MBEDTLS_MD_MAX_SIZE + 4 ];
+    size_t hash_olen;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "Reset SSL session for HRR" ) );
+
+#if defined(MBEDTLS_SHA256_C)
+    ret = ssl_hash_transcript_core( ssl, MBEDTLS_MD_SHA256,
+                                    hash_transcript,
+                                    sizeof( hash_transcript ),
+                                    &hash_olen );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 4, "ssl_hash_transcript_core", ret );
+        return( ret );
+    }
+    MBEDTLS_SSL_DEBUG_BUF( 4, "Truncated SHA-256 handshake transcript",
+                           hash_transcript, hash_olen );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    psa_hash_abort( &ssl->handshake->fin_sha256_psa );
+    psa_hash_setup( &ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
+#else
+    mbedtls_sha256_starts( &ssl->handshake->fin_sha256, 0 );
+#endif
+    ssl_update_checksum_sha256( ssl, hash_transcript, hash_olen );
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    ret = ssl_hash_transcript_core( ssl, MBEDTLS_MD_SHA384,
+                                    hash_transcript,
+                                    sizeof( hash_transcript ),
+                                    &hash_olen );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 4, "ssl_hash_transcript_core", ret );
+        return( ret );
+    }
+    MBEDTLS_SSL_DEBUG_BUF( 4, "Truncated SHA-384 handshake transcript",
+                           hash_transcript, hash_olen );
+#endif /* MBEDTLS_SHA512_C */
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
 
 #endif /* MBEDTLS_SSL_TLS_C */