Introduce ciphersuite handle type

This commit introduces an internal zero-cost abstraction layer for
SSL ciphersuites: Instead of addressing ciphersuites via pointers
to instances of mbedtls_ssl_ciphersuite_t and accessing their fields
directly, this commit introduces an opaque type

  mbedtls_ssl_ciphersuite_handle_t,

and getter functions

  mbedtls_ssl_suite_get_xxx()

operating on ciphersuite handles.

The role of NULL is played by a new macro constant

  MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE

which results of functions returning handles can be checked against.
(For example, when doing a lookup of a ciphersuite from a peer-provided
ciphersuite ID in the per's Hello message).

The getter functions have the validity of the handle as a precondition
and are undefined if the handle is invalid.

So far, there's only one implementation of this abstraction layer, namely

  mbedtls_ssl_ciphersuite_handle_t being mbedtls_ssl_ciphersuite_t const *

and

  getter functions being field accesses.

In subsequent commits, however, the abstraction layer will be useful
to save code in the situation where only a single ciphersuite is enabled.
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 84c78c4..c245145 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -801,7 +801,7 @@
     size_t mac_key_len;
     size_t iv_copy_len;
     unsigned keylen;
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+    mbedtls_ssl_ciphersuite_handle_t ciphersuite_info;
     const mbedtls_cipher_info_t *cipher_info;
     const mbedtls_md_info_t *md_info;
 
@@ -823,26 +823,28 @@
      * Get various info structures
      */
     ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite );
-    if( ciphersuite_info == NULL )
+    if( ciphersuite_info == MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %d not found",
                                     ciphersuite ) );
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
+    cipher_info = mbedtls_cipher_info_from_type(
+        mbedtls_ssl_suite_get_cipher( ciphersuite_info ) );
     if( cipher_info == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found",
-                                    ciphersuite_info->cipher ) );
+                       mbedtls_ssl_suite_get_cipher( ciphersuite_info ) ) );
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
-    md_info = mbedtls_md_info_from_type( ciphersuite_info->mac );
+    md_info = mbedtls_md_info_from_type(
+        mbedtls_ssl_suite_get_mac( ciphersuite_info ) );
     if( md_info == NULL )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found",
-                            ciphersuite_info->mac ) );
+                       mbedtls_ssl_suite_get_mac( ciphersuite_info ) ) );
         return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
     }
 
@@ -899,8 +901,8 @@
 
         transform->maclen = 0;
         mac_key_len = 0;
-        transform->taglen =
-            ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
+        transform->taglen = mbedtls_ssl_suite_get_flags( ciphersuite_info ) &
+            MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
 
         /* All modes haves 96-bit IVs;
          * GCM and CCM has 4 implicit and 8 explicit bytes
@@ -1338,15 +1340,15 @@
 int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
 {
     int ret;
-    const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
+    mbedtls_ssl_ciphersuite_handle_t  const ciphersuite_info =
         ssl->handshake->ciphersuite_info;
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
 
     /* Set PRF, calc_verify and calc_finished function pointers */
     ret = ssl_set_handshake_prfs( ssl->handshake,
-                                  ssl->minor_ver,
-                                  ciphersuite_info->mac );
+                            ssl->minor_ver,
+                            mbedtls_ssl_suite_get_mac( ciphersuite_info ) );
     if( ret != 0 )
     {
         MBEDTLS_SSL_DEBUG_RET( 1, "ssl_set_handshake_prfs", ret );
@@ -6070,7 +6072,7 @@
 /* No certificate support -> dummy functions */
 int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
 {
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->handshake->ciphersuite_info;
+    mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = ssl->handshake->ciphersuite_info;
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
 
@@ -6087,7 +6089,7 @@
 
 int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
 {
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->handshake->ciphersuite_info;
+    mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = ssl->handshake->ciphersuite_info;
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
 
@@ -6110,7 +6112,7 @@
     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
     size_t i, n;
     const mbedtls_x509_crt *crt;
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->handshake->ciphersuite_info;
+    mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = ssl->handshake->ciphersuite_info;
 
     MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
 
@@ -6474,7 +6476,7 @@
 static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl,
                                              int authmode )
 {
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+    mbedtls_ssl_ciphersuite_handle_t ciphersuite_info =
         ssl->handshake->ciphersuite_info;
 
     if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
@@ -6483,8 +6485,11 @@
 #if defined(MBEDTLS_SSL_SRV_C)
     if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER )
     {
-        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+        if( mbedtls_ssl_suite_get_key_exchange( ciphersuite_info ) ==
+            MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+        {
             return( SSL_CERTIFICATE_SKIP );
+        }
 
         if( authmode == MBEDTLS_SSL_VERIFY_NONE )
         {
@@ -6506,8 +6511,7 @@
                                          void *rs_ctx )
 {
     int verify_ret;
-    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
-        ssl->handshake->ciphersuite_info;
+    mbedtls_ssl_ciphersuite_handle_t ciphersuite_info =
     mbedtls_x509_crt *ca_chain;
     mbedtls_x509_crl *ca_crl;
 
@@ -6973,7 +6977,7 @@
 }
 
 void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
-                            const mbedtls_ssl_ciphersuite_t *ciphersuite_info )
+                            mbedtls_ssl_ciphersuite_handle_t ciphersuite_info )
 {
     ((void) ciphersuite_info);
 
@@ -6985,12 +6989,12 @@
 #endif
 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
 #if defined(MBEDTLS_SHA512_C)
-    if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
+    if( mbedtls_ssl_suite_get_mac( ciphersuite_info ) == MBEDTLS_MD_SHA384 )
         ssl->handshake->update_checksum = ssl_update_checksum_sha384;
     else
 #endif
 #if defined(MBEDTLS_SHA256_C)
-    if( ciphersuite_info->mac != MBEDTLS_MD_SHA384 )
+    if( mbedtls_ssl_suite_get_mac( ciphersuite_info ) != MBEDTLS_MD_SHA384 )
         ssl->handshake->update_checksum = ssl_update_checksum_sha256;
     else
 #endif
@@ -11242,7 +11246,7 @@
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
 int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
-                          const mbedtls_ssl_ciphersuite_t *ciphersuite,
+                          mbedtls_ssl_ciphersuite_handle_t ciphersuite,
                           int cert_endpoint,
                           uint32_t *flags )
 {
@@ -11266,7 +11270,7 @@
     if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
     {
         /* Server part of the key exchange */
-        switch( ciphersuite->key_exchange )
+        switch( mbedtls_ssl_suite_get_key_exchange( ciphersuite ) )
         {
             case MBEDTLS_KEY_EXCHANGE_RSA:
             case MBEDTLS_KEY_EXCHANGE_RSA_PSK: