Allow compile-time configuration of authentication mode

Introduces MBEDTLS_SSL_CONF_AUTHMODE to fix the authentication
mode (none, optional, mandatory) at compile-time.

Impact on code-size:

|  | GCC | ARMC5 | ARMC6 |
| --- | --- | --- | --- |
| `libmbedtls.a` before | 23487 | 24025 | 27885 |
| `libmbedtls.a` after  | 23379 | 23929 | 27727 |
| gain in Bytes | 108 | 96 | 157 |
diff --git a/configs/baremetal.h b/configs/baremetal.h
index bacc9d1..fad3992 100644
--- a/configs/baremetal.h
+++ b/configs/baremetal.h
@@ -80,6 +80,7 @@
 #define MBEDTLS_SSL_DTLS_CONNECTION_ID
 
 /* Compile-time fixed parts of the SSL configuration */
+#define MBEDTLS_SSL_CONF_AUTHMODE MBEDTLS_SSL_VERIFY_REQUIRED
 #define MBEDTLS_SSL_CONF_BADMAC_LIMIT 0
 #define MBEDTLS_SSL_CONF_ANTI_REPLAY MBEDTLS_SSL_ANTI_REPLAY_ENABLED
 #define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET \
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index ee292c5..3381b79 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -3450,6 +3450,8 @@
  * \{
  */
 
+//#define MBEDTLS_SSL_CONF_AUTHMODE MBEDTLS_SSL_VERIFY_REQUIRED
+
 /* DTLS-specific settings */
 //#define MBEDTLS_SSL_CONF_ANTI_REPLAY MBEDTLS_SSL_ANTI_REPLAY_ENABLED
 //#define MBEDTLS_SSL_CONF_BADMAC_LIMIT 0
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index dd546b8..492a324 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1049,7 +1049,9 @@
 
     unsigned int endpoint : 1;      /*!< 0: client, 1: server               */
     unsigned int transport : 1;     /*!< stream (TLS) or datagram (DTLS)    */
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
     unsigned int authmode : 2;      /*!< MBEDTLS_SSL_VERIFY_XXX             */
+#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */
     /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE          */
     unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX   */
 #if defined(MBEDTLS_ARC4_C)
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 49c6050..378db24 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -1085,6 +1085,21 @@
  * be fixed at compile time via one of MBEDTLS_SSL_SSL_CONF_XXX.
  */
 
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
+static inline int mbedtls_ssl_conf_get_authmode(
+    mbedtls_ssl_config  const *conf )
+{
+    return( conf->authmode );
+}
+#else /* !MBEDTLS_SSL_CONF_AUTHMODE */
+static inline int mbedtls_ssl_conf_get_authmode(
+    mbedtls_ssl_config const *conf )
+{
+    ((void) conf);
+    return( MBEDTLS_SSL_CONF_AUTHMODE );
+}
+#endif /* MBEDTLS_SSL_CONF_AUTHMODE */
+
 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
 #if !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT)
 static inline unsigned int mbedtls_ssl_conf_get_badmac_limit(
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index ecde1b0..9cc8be7 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -2848,7 +2848,7 @@
         authmode = ssl->handshake->sni_authmode;
     else
 #endif
-        authmode = ssl->conf->authmode;
+        authmode = mbedtls_ssl_conf_get_authmode( ssl->conf );
 
     if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ||
         authmode == MBEDTLS_SSL_VERIFY_NONE )
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index a79ce8d..0c05b50 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -6664,9 +6664,9 @@
 #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
     const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
                        ? ssl->handshake->sni_authmode
-                       : ssl->conf->authmode;
+                       : mbedtls_ssl_conf_get_authmode( ssl->conf );
 #else
-    const int authmode = ssl->conf->authmode;
+    const int authmode = mbedtls_ssl_conf_get_authmode( ssl->conf );
 #endif
     void *rs_ctx = NULL;
     mbedtls_x509_crt *chain = NULL;
@@ -8095,7 +8095,12 @@
 
 void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode )
 {
-    conf->authmode   = authmode;
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
+    conf->authmode = authmode;
+#else
+    ((void) conf);
+    ((void) authmode);
+#endif /* MBEDTLS_SSL_CONF_AUTHMODE */
 }
 
 #if defined(MBEDTLS_X509_CRT_PARSE_C)
@@ -10713,7 +10718,9 @@
 #if defined(MBEDTLS_SSL_CLI_C)
     if( endpoint == MBEDTLS_SSL_IS_CLIENT )
     {
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
         conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
+#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
         conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
 #endif
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index 2a7ca13..2557675 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -2578,6 +2578,14 @@
     }
 #endif /* MBEDTLS_PLATFORM_GMTIME_R_ALT */
 
+#if defined(MBEDTLS_SSL_CONF_AUTHMODE)
+    if( strcmp( "MBEDTLS_SSL_CONF_AUTHMODE", config ) == 0 )
+    {
+        MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_AUTHMODE );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_CONF_AUTHMODE */
+
 #if defined(MBEDTLS_SSL_CONF_ANTI_REPLAY)
     if( strcmp( "MBEDTLS_SSL_CONF_ANTI_REPLAY", config ) == 0 )
     {
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 9828576..dc5542e 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -293,6 +293,14 @@
 #define USAGE_SERIALIZATION ""
 #endif
 
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
+#define USAGE_AUTH_MODE \
+    "    auth_mode=%%s        default: (library default: none)\n" \
+    "                        options: none, optional, required\n"
+#else
+#define USAGE_AUTH_MODE ""
+#endif
+
 #define USAGE \
     "\n usage: ssl_client2 param=<>...\n"                   \
     "\n acceptable parameters:\n"                           \
@@ -317,8 +325,7 @@
     USAGE_DTLS                                              \
     USAGE_CID                                               \
     "\n"                                                    \
-    "    auth_mode=%%s        default: (library default: none)\n" \
-    "                        options: none, optional, required\n" \
+    USAGE_AUTH_MODE                                         \
     USAGE_IO                                                \
     "\n"                                                    \
     USAGE_PSK                                               \
@@ -1175,6 +1182,7 @@
             else
                 goto usage;
         }
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
         else if( strcmp( p, "auth_mode" ) == 0 )
         {
             if( strcmp( q, "none" ) == 0 )
@@ -1186,6 +1194,7 @@
             else
                 goto usage;
         }
+#endif
         else if( strcmp( p, "max_frag_len" ) == 0 )
         {
             if( strcmp( q, "512" ) == 0 )
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 3fcc120..89bd4f4 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -400,6 +400,14 @@
 #define USAGE_SERIALIZATION ""
 #endif
 
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
+#define USAGE_AUTH_MODE \
+    "    auth_mode=%%s        default: (library default: none)\n" \
+    "                        options: none, optional, required\n"
+#else
+#define USAGE_AUTH_MODE ""
+#endif
+
 #define USAGE \
     "\n usage: ssl_server2 param=<>...\n"                   \
     "\n acceptable parameters:\n"                           \
@@ -422,8 +430,7 @@
     USAGE_ANTI_REPLAY                                       \
     USAGE_BADMAC_LIMIT                                      \
     "\n"                                                    \
-    "    auth_mode=%%s        default: (library default: none)\n"      \
-    "                        options: none, optional, required\n" \
+    USAGE_AUTH_MODE                                         \
     "    cert_req_ca_list=%%d default: 1 (send ca list)\n"  \
     "                        options: 1 (send ca list), 0 (don't send)\n" \
     USAGE_IO                                                \
@@ -619,6 +626,7 @@
     return( ret );
 }
 
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
 /*
  * Return authmode from string, or -1 on error
  */
@@ -633,6 +641,7 @@
 
     return( -1 );
 }
+#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */
 
 /*
  * Used by sni_parse and psk_parse to handle coma-separated lists
@@ -1787,11 +1796,13 @@
             else
                 goto usage;
         }
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
         else if( strcmp( p, "auth_mode" ) == 0 )
         {
             if( ( opt.auth_mode = get_auth_mode( q ) ) < 0 )
                 goto usage;
         }
+#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */
         else if( strcmp( p, "cert_req_ca_list" ) == 0 )
         {
             opt.cert_req_ca_list = atoi( q );
@@ -2445,8 +2456,10 @@
     }
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
     if( opt.auth_mode != DFL_AUTH_MODE )
         mbedtls_ssl_conf_authmode( &conf, opt.auth_mode );
+#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */
 
     if( opt.cert_req_ca_list != DFL_CERT_REQ_CA_LIST )
         mbedtls_ssl_conf_cert_req_ca_list( &conf, opt.cert_req_ca_list );
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 87c1d24..4c3fc15 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -529,6 +529,20 @@
     fi
 }
 
+check_cmdline_authmode_compat() {
+    __VAL="$( get_config_value_or_default "MBEDTLS_SSL_CONF_AUTHMODE" )"
+    if [ ! -z "$__VAL" ]; then
+        extract_cmdline_argument "auth_mode"
+        if [ "$__ARG" = "none" ] && [ "$__VAL" != "0" ]; then
+            SKIP_NEXT="YES";
+        elif [ "$__ARG" = "optional" ] && [ "$__VAL" != "1" ]; then
+            SKIP_NEXT="YES"
+        elif [ "$__ARG" = "required" ] && [ "$__VAL" != "2" ]; then
+            SKIP_NEXT="YES"
+        fi
+    fi
+}
+
 # Go through all options that can be hardcoded at compile-time and
 # detect whether the command line configures them in a conflicting
 # way. If so, skip the test. Otherwise, remove the corresponding
@@ -552,6 +566,9 @@
     # DTLS bad MAC limit
     check_cmdline_param_compat "badmac_limit" \
                                "MBEDTLS_SSL_CONF_BADMAC_LIMIT"
+
+    # Authentication mode
+    check_cmdline_authmode_compat
 }
 
 # Usage: run_test name [-p proxy_cmd] srv_cmd cli_cmd cli_exit [option [...]]