Merged ECDSA-based key-exchange and ciphersuites into development

Conflicts:
	include/polarssl/config.h
	library/ssl_cli.c
	library/ssl_srv.c
	library/ssl_tls.c
diff --git a/ChangeLog b/ChangeLog
index 505d90a..36c1779 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,6 +20,8 @@
    * Support for session tickets (RFC 5077)
 
 Changes
+   * Ability to enable / disable SSL v3 / TLS 1.0 / TLS 1.1 / TLS 1.2
+     individually
    * Introduced separate SSL Ciphersuites module that is based on
      Cipher and MD information
    * Internals for SSL module adapted to have separate IV pointer that is
@@ -29,6 +31,7 @@
    * Split up the GCM module into a starts/update/finish cycle
    * Client and server now filter sent and accepted ciphersuites on minimum
      and maximum protocol version
+   * Ability to disable server_name extension (RFC 6066)
    * Renamed error_strerror() to the less conflicting polarssl_strerror()
      (Ability to keep old as well with POLARSSL_ERROR_STRERROR_BC)
    * SHA2 renamed to SHA256, SHA4 renamed to SHA512 and functions accordingly
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index 3c709fe..c1a1269 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -560,6 +560,54 @@
 #define POLARSSL_SSL_MAX_FRAGMENT_LENGTH
 
 /**
+ * \def POLARSSL_SSL_PROTO_SSL3
+ *
+ * Enable support for SSL 3.0
+ *
+ * Requires: POLARSSL_MD5_C
+ *           POLARSSL_SHA1_C
+ *
+ * Comment this macro to disable support for SSL 3.0
+ */
+#define POLARSSL_SSL_PROTO_SSL3
+
+/**
+ * \def POLARSSL_SSL_PROTO_TLS1
+ *
+ * Enable support for TLS 1.0
+ *
+ * Requires: POLARSSL_MD5_C
+ *           POLARSSL_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.0
+ */
+#define POLARSSL_SSL_PROTO_TLS1
+
+/**
+ * \def POLARSSL_SSL_PROTO_TLS1_1
+ *
+ * Enable support for TLS 1.1
+ *
+ * Requires: POLARSSL_MD5_C
+ *           POLARSSL_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.1
+ */
+#define POLARSSL_SSL_PROTO_TLS1_1
+
+/**
+ * \def POLARSSL_SSL_PROTO_TLS1_2
+ *
+ * Enable support for TLS 1.2
+ *
+ * Requires: POLARSSL_SHA256_C or POLARSSL_SHA512_C
+ *           (Depends on ciphersuites)
+ *
+ * Comment this macro to disable support for TLS 1.2
+ */
+#define POLARSSL_SSL_PROTO_TLS1_2
+
+/**
  * \def POLARSSL_SSL_SESSION_TICKETS
  *
  * Enable support for RFC 5077 session tickets in SSL
@@ -572,6 +620,15 @@
 #define POLARSSL_SSL_SESSION_TICKETS
 
 /**
+ * \def POLARSSL_SSL_SERVER_NAME_INDICATION
+ *
+ * Enable support for RFC 6066 server name indication (SNI) in SSL
+ *
+ * Comment this macro to disable support for server name indication in SSL
+ */
+#define POLARSSL_SSL_SERVER_NAME_INDICATION
+
+/**
  * \def POLARSSL_SSL_TRUNCATED_HMAC
  *
  * Enable support for RFC 6066 truncated HMAC in SSL
@@ -1262,7 +1319,8 @@
  * Caller:  library/ssl_cli.c
  *          library/ssl_srv.c
  *
- * Requires: POLARSSL_MD5_C, POLARSSL_SHA1_C, POLARSSL_CIPHER_C, POLARSSL_PK_C
+ * Requires: POLARSSL_CIPHER_C, POLARSSL_PK_C, POLARSSL_MD_C
+ *           and at least one of the POLARSSL_SSL_PROTO_* defines
  *
  * This module is required for SSL/TLS.
  */
@@ -1496,9 +1554,8 @@
 #error "POLARSSL_SSL_CLI_C defined, but not all prerequisites"
 #endif
 
-#if defined(POLARSSL_SSL_TLS_C) && ( !defined(POLARSSL_MD5_C) ||        \
-    !defined(POLARSSL_SHA1_C) || !defined(POLARSSL_CIPHER_C) ) ||       \
-    !defined(POLARSSL_PK_C)
+#if defined(POLARSSL_SSL_TLS_C) && ( !defined(POLARSSL_CIPHER_C) ||     \
+    !defined(POLARSSL_PK_C) || !defined(POLARSSL_MD_C) )
 #error "POLARSSL_SSL_TLS_C defined, but not all prerequisites"
 #endif
 
@@ -1506,6 +1563,28 @@
 #error "POLARSSL_SSL_SRV_C defined, but not all prerequisites"
 #endif
 
+#if defined(POLARSSL_SSL_TLS_C) && (!defined(POLARSSL_SSL_PROTO_SSL3) && \
+    !defined(POLARSSL_SSL_PROTO_TLS1) && !defined(POLARSSL_SSL_PROTO_TLS1_1) && \
+    !defined(POLARSSL_SSL_PROTO_TLS1_2))
+#error "POLARSSL_SSL_TLS_C defined, but no protocols are active"
+#endif
+
+#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_SSL3) && \
+    defined(POLARSSL_SSL_PROTO_TLS1_1) && !defined(POLARSSL_SSL_PROTO_TLS1))
+#error "Illegal protocol selection"
+#endif
+
+#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_TLS1) && \
+    defined(POLARSSL_SSL_PROTO_TLS1_2) && !defined(POLARSSL_SSL_PROTO_TLS1_1))
+#error "Illegal protocol selection"
+#endif
+
+#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_SSL3) && \
+    defined(POLARSSL_SSL_PROTO_TLS1_2) && (!defined(POLARSSL_SSL_PROTO_TLS1) || \
+    !defined(POLARSSL_SSL_PROTO_TLS1_1)))
+#error "Illegal protocol selection"
+#endif
+
 #if defined(POLARSSL_SSL_SESSION_TICKETS) && defined(POLARSSL_SSL_TLS_C) && \
     ( !defined(POLARSSL_AES_C) || !defined(POLARSSL_SHA256_C) )
 #error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites"
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 0227bb8..56a6378 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -31,14 +31,28 @@
 #include "net.h"
 #include "bignum.h"
 
-#include "md5.h"
-#include "sha1.h"
-#include "sha256.h"
-#include "sha512.h"
-#include "aes.h"
-
 #include "ssl_ciphersuites.h"
 
+#if defined(POLARSSL_MD5_C)
+#include "md5.h"
+#endif
+
+#if defined(POLARSSL_SHA1_C)
+#include "sha1.h"
+#endif
+
+#if defined(POLARSSL_SHA256_C)
+#include "sha256.h"
+#endif
+
+#if defined(POLARSSL_SHA512_C)
+#include "sha512.h"
+#endif
+
+#if defined(POLARSSL_AES_C)
+#include "aes.h"
+#endif
+
 #if defined(POLARSSL_X509_PARSE_C)
 #include "x509.h"
 #endif
@@ -121,6 +135,44 @@
 #define SSL_MINOR_VERSION_2             2   /*!< TLS v1.1 */
 #define SSL_MINOR_VERSION_3             3   /*!< TLS v1.2 */
 
+/* Determine minimum supported version */
+#define SSL_MIN_MAJOR_VERSION           SSL_MAJOR_VERSION_3
+
+#if defined(POLARSSL_SSL_PROTO_SSL3)
+#define SSL_MIN_MINOR_VERSION           SSL_MINOR_VERSION_0
+#else
+#if defined(POLARSSL_SSL_PROTO_TLS1)
+#define SSL_MIN_MINOR_VERSION           SSL_MINOR_VERSION_1
+#else
+#if defined(POLARSSL_SSL_PROTO_TLS1_1)
+#define SSL_MIN_MINOR_VERSION           SSL_MINOR_VERSION_2
+#else
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#define SSL_MIN_MINOR_VERSION           SSL_MINOR_VERSION_3
+#endif
+#endif
+#endif
+#endif
+
+/* Determine maximum supported version */
+#define SSL_MAX_MAJOR_VERSION           SSL_MAJOR_VERSION_3
+
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#define SSL_MAX_MINOR_VERSION           SSL_MINOR_VERSION_3
+#else
+#if defined(POLARSSL_SSL_PROTO_TLS1_1)
+#define SSL_MAX_MINOR_VERSION           SSL_MINOR_VERSION_2
+#else
+#if defined(POLARSSL_SSL_PROTO_TLS1)
+#define SSL_MAX_MINOR_VERSION           SSL_MINOR_VERSION_1
+#else
+#if defined(POLARSSL_SSL_PROTO_SSL3)
+#define SSL_MAX_MINOR_VERSION           SSL_MINOR_VERSION_0
+#endif
+#endif
+#endif
+#endif
+
 /* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c
  * NONE must be zero so that memset()ing structure to zero works */
 #define SSL_MAX_FRAG_LEN_NONE           0   /*!< don't use this extension   */
@@ -397,9 +449,11 @@
     unsigned char iv_enc[16];           /*!<  IV (encryption)         */
     unsigned char iv_dec[16];           /*!<  IV (decryption)         */
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
     /* Needed only for SSL v3.0 secret */
     unsigned char mac_enc[32];          /*!<  SSL v3.0 secret (enc)   */
     unsigned char mac_dec[32];          /*!<  SSL v3.0 secret (dec)   */
+#endif /* POLARSSL_SSL_PROTO_SSL3 */
 
     md_context_t md_ctx_enc;            /*!<  MAC (encryption)        */
     md_context_t md_ctx_dec;            /*!<  MAC (decryption)        */
@@ -441,12 +495,19 @@
     /*
      * Checksum contexts
      */
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
        md5_context fin_md5;
       sha1_context fin_sha1;
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SHA256_C)
     sha256_context fin_sha256;
+#endif
 #if defined(POLARSSL_SHA512_C)
     sha512_context fin_sha512;
 #endif
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
     void (*update_checksum)(ssl_context *, const unsigned char *, size_t);
     void (*calc_verify)(ssl_context *, unsigned char *);
@@ -508,7 +569,6 @@
     int (*f_send)(void *, const unsigned char *, size_t);
     int (*f_get_cache)(void *, ssl_session *);
     int (*f_set_cache)(void *, const ssl_session *);
-    int (*f_sni)(void *, ssl_context *, const unsigned char *, size_t);
 
     void *p_rng;                /*!< context for the RNG function     */
     void *p_dbg;                /*!< context for the debug function   */
@@ -516,9 +576,13 @@
     void *p_send;               /*!< context for writing operations   */
     void *p_get_cache;          /*!< context for cache retrieval      */
     void *p_set_cache;          /*!< context for cache store          */
-    void *p_sni;                /*!< context for SNI extension        */
     void *p_hw_data;            /*!< context for HW acceleration      */
 
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
+    int (*f_sni)(void *, ssl_context *, const unsigned char *, size_t);
+    void *p_sni;                /*!< context for SNI extension        */
+#endif
+
 #if defined(POLARSSL_X509_PARSE_C)
     int (*f_vrfy)(void *, x509_cert *, int, int *);
     void *p_vrfy;               /*!< context for verification         */
@@ -629,11 +693,13 @@
     size_t         psk_identity_len;
 #endif
 
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
     /*
-     * TLS extensions
+     * SNI extension
      */
     unsigned char *hostname;
     size_t         hostname_len;
+#endif
 
     /*
      * Secure renegotiation
@@ -992,6 +1058,7 @@
 int ssl_set_dh_param_ctx( ssl_context *ssl, dhm_context *dhm_ctx );
 #endif
 
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
 /**
  * \brief          Set hostname for ServerName TLS extension
  *                 (client-side only)
@@ -1027,15 +1094,17 @@
                   int (*f_sni)(void *, ssl_context *, const unsigned char *,
                                size_t),
                   void *p_sni );
+#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
 
 /**
  * \brief          Set the maximum supported version sent from the client side
  *                 and/or accepted at the server side
- *                 (Default: SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3)
+ *                 (Default: SSL_MAX_MAJOR_VERSION, SSL_MAX_MINOR_VERSION)
  *
- *                 Note: This prevents ciphersuites from 'higher' versions to
- *                 be ignored.
- * 
+ *                 Note: This ignores ciphersuites from 'higher' versions.
+ *                 Note: Input outside of the SSL_MAX_XXXXX_VERSION and
+ *                       SSL_MIN_XXXXX_VERSION range is ignored.
+ *
  * \param ssl      SSL context
  * \param major    Major version number (only SSL_MAJOR_VERSION_3 supported)
  * \param minor    Minor version number (SSL_MINOR_VERSION_0,
@@ -1047,7 +1116,10 @@
 
 /**
  * \brief          Set the minimum accepted SSL/TLS protocol version
- *                 (Default: SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0)
+ *                 (Default: SSL_MIN_MAJOR_VERSION, SSL_MIN_MINOR_VERSION)
+ *
+ *                 Note: Input outside of the SSL_MAX_XXXXX_VERSION and
+ *                       SSL_MIN_XXXXX_VERSION range is ignored.
  *
  * \param ssl      SSL context
  * \param major    Major version number (only SSL_MAJOR_VERSION_3 supported)
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index a821a31..18094a3 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -51,6 +51,7 @@
 #include <time.h>
 #endif
 
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
 static void ssl_write_hostname_ext( ssl_context *ssl,
                                     unsigned char *buf,
                                     size_t *olen )
@@ -100,6 +101,7 @@
 
     *olen = ssl->hostname_len + 9;
 }
+#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
 
 static void ssl_write_renegotiation_ext( ssl_context *ssl,
                                          unsigned char *buf,
@@ -129,6 +131,7 @@
     *olen = 5 + ssl->verify_data_len;
 }
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
 static void ssl_write_signature_algorithms_ext( ssl_context *ssl,
                                                 unsigned char *buf,
                                                 size_t *olen )
@@ -220,6 +223,7 @@
 
     *olen = 6 + sig_alg_len;
 }
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
 static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl,
@@ -406,8 +410,8 @@
 
     if( ssl->max_major_ver == 0 && ssl->max_minor_ver == 0 )
     {
-        ssl->max_major_ver = SSL_MAJOR_VERSION_3;
-        ssl->max_minor_ver = SSL_MINOR_VERSION_3;
+        ssl->max_major_ver = SSL_MAX_MAJOR_VERSION;
+        ssl->max_minor_ver = SSL_MAX_MINOR_VERSION;
     }
 
     /*
@@ -554,14 +558,18 @@
 
     // First write extensions, then the total length
     //
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
     ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen );
     ext_len += olen;
+#endif
 
     ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
     ext_len += olen;
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
     ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
     ext_len += olen;
+#endif
 
 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
     ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
@@ -1178,6 +1186,7 @@
 #endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
           POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
     defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
     defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
@@ -1229,6 +1238,7 @@
 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED ||
           POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
           POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
 static int ssl_parse_server_key_exchange( ssl_context *ssl )
 {
@@ -1243,7 +1253,7 @@
     md_type_t md_alg = POLARSSL_MD_NONE;
     size_t hashlen;
     pk_type_t pk_alg = POLARSSL_PK_NONE;
-#endif 
+#endif
 
     SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
 
@@ -1352,6 +1362,7 @@
     {
         params_len = p - ( ssl->in_msg + 4 );
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
         /*
          * Handle the digitally-signed structure
          */
@@ -1371,6 +1382,7 @@
             }
         }
         else
+#endif
         {
             pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
         }
@@ -1396,6 +1408,8 @@
         /*
          * Compute the hash that has been signed
          */
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
         if( md_alg == POLARSSL_MD_NONE )
         {
             md5_context md5;
@@ -1427,6 +1441,9 @@
             sha1_finish( &sha1, hash + 16 );
         }
         else
+#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \
+          POLARSSL_SSL_PROTO_TLS1_1 */
+        if( md_alg != POLARSSL_MD_NONE )
         {
             md_context_t ctx;
 
@@ -1452,6 +1469,11 @@
             md_finish( &ctx, hash );
             md_free_ctx( &ctx );
         }
+        else
+        {
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+        }
 
         SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
                 (unsigned int) ( md_info_from_type( md_alg ) )->size );
@@ -1489,7 +1511,7 @@
     int ret;
     unsigned char *buf, *p;
     size_t n = 0, m = 0;
-    size_t cert_type_len = 0, sig_alg_len = 0, dn_len = 0;
+    size_t cert_type_len = 0, dn_len = 0;
 
     SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
 
@@ -1571,10 +1593,11 @@
         return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
     }
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
     if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
     {
-        sig_alg_len = ( ( buf[5 + n] <<  8 )
-                      | ( buf[6 + n]       ) );
+        size_t sig_alg_len = ( ( buf[5 + n] <<  8 )
+                             | ( buf[6 + n]       ) );
 
         p = buf + 7 + n;
         m += 2;
@@ -1586,6 +1609,7 @@
             return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
         }
     }
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
     dn_len = ( ( buf[5 + m + n] <<  8 )
              | ( buf[6 + m + n]       ) );
@@ -1864,11 +1888,14 @@
             return( ret );
         }
 
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_2)
         if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
         {
             ssl->out_msg[4] = (unsigned char)( n >> 8 );
             ssl->out_msg[5] = (unsigned char)( n      );
         }
+#endif
 
     }
     else
@@ -1960,6 +1987,8 @@
      */
     ssl->handshake->calc_verify( ssl, hash );
 
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
     if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
     {
         /*
@@ -1988,6 +2017,10 @@
         }
     }
     else
+#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \
+          POLARSSL_SSL_PROTO_TLS1_1 */
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
     {
         /*
          * digitally-signed struct {
@@ -2019,9 +2052,14 @@
 
         /* Info from md_alg will be used instead */
         hashlen = 0;
-
         offset = 2;
     }
+    else
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
+    {
+        SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+    }
 
     if( ( ret = pk_sign( ssl->pk_key, md_alg, hash_start, hashlen,
                          ssl->out_msg + 6 + offset, &n,
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 53f12f4..dc684ad 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -336,6 +336,7 @@
 }
 #endif /* POLARSSL_SSL_SESSION_TICKETS */
 
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
 static int ssl_parse_servername_ext( ssl_context *ssl,
                                      const unsigned char *buf,
                                      size_t len )
@@ -385,6 +386,7 @@
 
     return( 0 );
 }
+#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
 
 static int ssl_parse_renegotiation_info( ssl_context *ssl,
                                          const unsigned char *buf,
@@ -424,6 +426,7 @@
     return( 0 );
 }
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
 static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
                                                const unsigned char *buf,
                                                size_t len )
@@ -490,6 +493,7 @@
 
     return( 0 );
 }
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
 static int ssl_parse_supported_elliptic_curves( ssl_context *ssl,
@@ -1154,6 +1158,7 @@
         }
         switch( ext_id )
         {
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
         case TLS_EXT_SERVERNAME:
             SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) );
             if( ssl->f_sni == NULL )
@@ -1163,6 +1168,7 @@
             if( ret != 0 )
                 return( ret );
             break;
+#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
 
         case TLS_EXT_RENEGOTIATION_INFO:
             SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
@@ -1173,6 +1179,7 @@
                 return( ret );
             break;
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
         case TLS_EXT_SIG_ALG:
             SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
             if( ssl->renegotiation == SSL_RENEGOTIATION )
@@ -1182,6 +1189,7 @@
             if( ret != 0 )
                 return( ret );
             break;
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
 #if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
         case TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
@@ -1733,6 +1741,8 @@
     p[0] = ct_len++;
     p += ct_len;
 
+    sa_len = 0;
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
     /*
      * Add signature_algorithms for verify (TLS 1.2)
      *
@@ -1746,7 +1756,6 @@
      *     enum { (255) } HashAlgorithm;
      *     enum { (255) } SignatureAlgorithm;
      */
-    sa_len = 0;
     if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
     {
         /*
@@ -1778,6 +1787,7 @@
         sa_len += 2;
         p += sa_len;
     }
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
     /*
      * DistinguishedName certificate_authorities<0..2^16-1>;
@@ -1826,7 +1836,7 @@
     size_t n = 0, len;
     unsigned char hash[64];
     md_type_t md_alg = POLARSSL_MD_NONE;
-    unsigned int hashlen;
+    unsigned int hashlen = 0;
     unsigned char *p = ssl->out_msg + 4;
     unsigned char *dig_signed = p;
     size_t dig_signed_len = 0;
@@ -1953,6 +1963,7 @@
         /*
          * Choose hash algorithm. NONE means MD5 + SHA1 here.
          */
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
         if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
         {
             md_alg = ssl_md_alg_from_hash( ssl->handshake->sig_alg );
@@ -1963,20 +1974,26 @@
                 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
             }
         }
-        else if ( ciphersuite_info->key_exchange ==
+        else
+#endif
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
+        if ( ciphersuite_info->key_exchange ==
                   POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA )
         {
             md_alg = POLARSSL_MD_SHA1;
         }
         else
+#endif
         {
             md_alg = POLARSSL_MD_NONE;
         }
 
-
         /*
          * Compute the hash to be signed
          */
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
         if( md_alg == POLARSSL_MD_NONE )
         {
             md5_context md5;
@@ -2008,6 +2025,9 @@
             hashlen = 36;
         }
         else
+#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \
+          POLARSSL_SSL_PROTO_TLS1_1 */
+        if( md_alg != POLARSSL_MD_NONE )
         {
             md_context_t ctx;
 
@@ -2039,6 +2059,11 @@
             }
 
         }
+        else
+        {
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+        }
 
         SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
                 (unsigned int) ( md_info_from_type( md_alg ) )->size );
@@ -2052,6 +2077,7 @@
             return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
         }
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
         if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
         {
             *(p++) = ssl->handshake->sig_alg;
@@ -2059,6 +2085,7 @@
 
             n += 2;
         }
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
         if( ( ret = pk_sign( ssl->pk_key, md_alg, hash, hashlen,
                         p + 2 , &signature_len,
@@ -2213,6 +2240,8 @@
     n = pk_get_len( ssl->pk_key );
     ssl->handshake->pmslen = 48;
 
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_2)
     if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
     {
         i += 2;
@@ -2223,6 +2252,7 @@
             return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
         }
     }
+#endif
 
     if( ssl->in_hslen != i + n )
     {
@@ -2434,6 +2464,8 @@
         *(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len >> 8 );
         *(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len      );
 
+        n = ssl->handshake->dhm_ctx.len;
+
         if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
                                       p, &n ) ) != 0 )
         {
@@ -2517,7 +2549,9 @@
     unsigned char hash[48];
     unsigned char *hash_start = hash;
     size_t hashlen;
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
     pk_type_t pk_alg;
+#endif
     md_type_t md_alg;
     const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
 
@@ -2568,6 +2602,8 @@
      *    6+n . 6+n+m signature (m = sig_len)
      */
 
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
     if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
     {
         sa_len = 0;
@@ -2585,6 +2621,9 @@
         }
     }
     else
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
     {
         sa_len = 2;
 
@@ -2622,7 +2661,12 @@
             SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
             return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
         }
-
+    }
+    else
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
+    {
+        SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
     }
 
     sig_len = ( ssl->in_msg[4 + sa_len] << 8 ) | ssl->in_msg[5 + sa_len];
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 00f79f4..292c96c 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -35,12 +35,12 @@
 
 #if defined(POLARSSL_SSL_TLS_C)
 
-#include "polarssl/aes.h"
+#include "polarssl/debug.h"
+#include "polarssl/ssl.h"
+
 #include "polarssl/arc4.h"
 #include "polarssl/camellia.h"
 #include "polarssl/des.h"
-#include "polarssl/debug.h"
-#include "polarssl/ssl.h"
 
 #if defined(POLARSSL_GCM_C)
 #include "polarssl/gcm.h"
@@ -134,6 +134,7 @@
 /*
  * Key material generation
  */
+#if defined(POLARSSL_SSL_PROTO_SSL3)
 static int ssl3_prf( const unsigned char *secret, size_t slen,
                      const char *label,
                      const unsigned char *random, size_t rlen,
@@ -178,7 +179,9 @@
 
     return( 0 );
 }
+#endif /* POLARSSL_SSL_PROTO_SSL3 */
 
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1)
 static int tls1_prf( const unsigned char *secret, size_t slen,
                      const char *label,
                      const unsigned char *random, size_t rlen,
@@ -239,7 +242,10 @@
 
     return( 0 );
 }
+#endif /* POLARSSL_SSL_PROTO_TLS1) || POLARSSL_SSL_PROTO_TLS1_1 */
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SHA256_C)
 static int tls_prf_sha256( const unsigned char *secret, size_t slen,
                            const char *label,
                            const unsigned char *random, size_t rlen,
@@ -279,6 +285,7 @@
 
     return( 0 );
 }
+#endif /* POLARSSL_SHA256_C */
 
 #if defined(POLARSSL_SHA512_C)
 static int tls_prf_sha384( const unsigned char *secret, size_t slen,
@@ -320,25 +327,39 @@
 
     return( 0 );
 }
-#endif
+#endif /* POLARSSL_SHA512_C */
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
 static void ssl_update_checksum_start(ssl_context *, const unsigned char *, size_t);
+
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
 static void ssl_update_checksum_md5sha1(ssl_context *, const unsigned char *, size_t);
-static void ssl_update_checksum_sha256(ssl_context *, const unsigned char *, size_t);
+#endif
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
 static void ssl_calc_verify_ssl(ssl_context *,unsigned char *);
-static void ssl_calc_verify_tls(ssl_context *,unsigned char *);
-static void ssl_calc_verify_tls_sha256(ssl_context *,unsigned char *);
-
 static void ssl_calc_finished_ssl(ssl_context *,unsigned char *,int);
+#endif
+
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1)
+static void ssl_calc_verify_tls(ssl_context *,unsigned char *);
 static void ssl_calc_finished_tls(ssl_context *,unsigned char *,int);
+#endif
+
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SHA256_C)
+static void ssl_update_checksum_sha256(ssl_context *, const unsigned char *, size_t);
+static void ssl_calc_verify_tls_sha256(ssl_context *,unsigned char *);
 static void ssl_calc_finished_tls_sha256(ssl_context *,unsigned char *,int);
+#endif
 
 #if defined(POLARSSL_SHA512_C)
 static void ssl_update_checksum_sha384(ssl_context *, const unsigned char *, size_t);
 static void ssl_calc_verify_tls_sha384(ssl_context *,unsigned char *);
 static void ssl_calc_finished_tls_sha384(ssl_context *,unsigned char *,int);
 #endif
+#endif
 
 int ssl_derive_keys( ssl_context *ssl )
 {
@@ -351,7 +372,6 @@
     unsigned int iv_copy_len;
     const cipher_info_t *cipher_info;
     const md_info_t *md_info;
-    int ret;
 
     ssl_session *session = ssl->session_negotiate;
     ssl_transform *transform = ssl->transform_negotiate;
@@ -378,33 +398,49 @@
     /*
      * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions
      */
+#if defined(POLARSSL_SSL_PROTO_SSL3)
     if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
     {
         handshake->tls_prf = ssl3_prf;
         handshake->calc_verify = ssl_calc_verify_ssl;
         handshake->calc_finished = ssl_calc_finished_ssl;
     }
-    else if( ssl->minor_ver < SSL_MINOR_VERSION_3 )
+    else
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1)
+    if( ssl->minor_ver < SSL_MINOR_VERSION_3 )
     {
         handshake->tls_prf = tls1_prf;
         handshake->calc_verify = ssl_calc_verify_tls;
         handshake->calc_finished = ssl_calc_finished_tls;
     }
+    else
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
 #if defined(POLARSSL_SHA512_C)
-    else if( transform->ciphersuite_info->mac ==
-             POLARSSL_MD_SHA384 )
+    if( ssl->minor_ver == SSL_MINOR_VERSION_3 &&
+        transform->ciphersuite_info->mac == POLARSSL_MD_SHA384 )
     {
         handshake->tls_prf = tls_prf_sha384;
         handshake->calc_verify = ssl_calc_verify_tls_sha384;
         handshake->calc_finished = ssl_calc_finished_tls_sha384;
     }
-#endif
     else
+#endif
+#if defined(POLARSSL_SHA256_C)
+    if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
     {
         handshake->tls_prf = tls_prf_sha256;
         handshake->calc_verify = ssl_calc_verify_tls_sha256;
         handshake->calc_finished = ssl_calc_finished_tls_sha256;
     }
+    else
+#endif
+#endif
+    {
+        SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+    }
 
     /*
      * SSLv3:
@@ -413,7 +449,7 @@
      *     MD5( premaster + SHA1( 'BB'  + premaster + randbytes ) ) +
      *     MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
      *
-     * TLSv1:
+     * TLSv1+:
      *   master = PRF( premaster, "master secret", randbytes )[0..47]
      */
     if( handshake->resume == 0 )
@@ -478,6 +514,8 @@
     {
         if( md_info->type != POLARSSL_MD_NONE )
         {
+            int ret;
+
             if( ( ret = md_init_ctx( &transform->md_ctx_enc, md_info ) ) != 0 )
             {
                 SSL_DEBUG_RET( 1, "md_init_ctx", ret );
@@ -559,16 +597,27 @@
                 iv_copy_len );
     }
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
     if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
     {
         memcpy( transform->mac_enc, mac_enc, transform->maclen );
         memcpy( transform->mac_dec, mac_dec, transform->maclen );
     }
     else
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver >= SSL_MINOR_VERSION_1 )
     {
         md_hmac_starts( &transform->md_ctx_enc, mac_enc, transform->maclen );
         md_hmac_starts( &transform->md_ctx_dec, mac_dec, transform->maclen );
     }
+    else
+#endif
+    {
+        SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+    }
 
 #if defined(POLARSSL_SSL_HW_RECORD_ACCEL)
     if( ssl_hw_record_init != NULL)
@@ -677,6 +726,7 @@
     return( 0 );
 }
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
 void ssl_calc_verify_ssl( ssl_context *ssl, unsigned char hash[36] )
 {
     md5_context md5;
@@ -717,7 +767,9 @@
 
     return;
 }
+#endif
 
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1)
 void ssl_calc_verify_tls( ssl_context *ssl, unsigned char hash[36] )
 {
     md5_context md5;
@@ -736,7 +788,10 @@
 
     return;
 }
+#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 */
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SHA256_C)
 void ssl_calc_verify_tls_sha256( ssl_context *ssl, unsigned char hash[32] )
 {
     sha256_context sha256;
@@ -751,6 +806,7 @@
 
     return;
 }
+#endif /* POLARSSL_SHA256_C */
 
 #if defined(POLARSSL_SHA512_C)
 void ssl_calc_verify_tls_sha384( ssl_context *ssl, unsigned char hash[48] )
@@ -767,8 +823,10 @@
 
     return;
 }
-#endif
+#endif /* POLARSSL_SHA512_C */
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
 /*
  * SSLv3.0 MAC functions
  */
@@ -809,6 +867,7 @@
     md_update( md_ctx, buf + len, md_size );
     md_finish( md_ctx, buf + len          );
 }
+#endif /* POLARSSL_SSL_PROTO_SSL3 */
 
 /*
  * Encryption/decryption functions
@@ -822,6 +881,7 @@
     /*
      * Add MAC then encrypt
      */
+#if defined(POLARSSL_SSL_PROTO_SSL3)
     if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
     {
         ssl_mac( &ssl->transform_out->md_ctx_enc,
@@ -830,6 +890,10 @@
                   ssl->out_ctr, ssl->out_msgtype );
     }
     else
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver >= SSL_MINOR_VERSION_1 )
     {
         md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 13 );
         md_hmac_update( &ssl->transform_out->md_ctx_enc,
@@ -838,6 +902,12 @@
                          ssl->out_msg + ssl->out_msglen );
         md_hmac_reset( &ssl->transform_out->md_ctx_enc );
     }
+    else
+#endif
+    {
+        SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+    }
 
     SSL_DEBUG_BUF( 4, "computed mac",
                    ssl->out_msg + ssl->out_msglen, ssl->transform_out->maclen );
@@ -953,6 +1023,7 @@
         enc_msglen = ssl->out_msglen;
         enc_msg = ssl->out_msg;
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2)
         /*
          * Prepend per-record IV for block cipher in TLS v1.1 and up as per
          * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
@@ -977,6 +1048,7 @@
             enc_msglen = ssl->out_msglen;
             ssl->out_msglen += ssl->transform_out->ivlen;
         }
+#endif /* POLARSSL_SSL_PROTO_TLS1_1 || POLARSSL_SSL_PROTO_TLS1_2 */
 
         SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
                             "including %d bytes of IV and %d bytes of padding",
@@ -1141,8 +1213,10 @@
             return( POLARSSL_ERR_SSL_INVALID_MAC );
         }
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2)
         if( ssl->minor_ver >= SSL_MINOR_VERSION_2 )
             minlen += ssl->transform_in->ivlen;
+#endif
 
         if( ssl->in_msglen < minlen + ssl->transform_in->ivlen ||
             ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 )
@@ -1156,6 +1230,7 @@
         dec_msg = ssl->in_msg;
         dec_msg_result = ssl->in_msg;
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2)
         /*
          * Initialize for prepended IV for block cipher in TLS v1.1 and up
          */
@@ -1167,6 +1242,7 @@
             for( i = 0; i < ssl->transform_in->ivlen; i++ )
                 ssl->transform_in->iv_dec[i] = ssl->in_iv[i];
         }
+#endif /* POLARSSL_SSL_PROTO_TLS1_1 || POLARSSL_SSL_PROTO_TLS1_2 */
 
         switch( ssl->transform_in->ciphersuite_info->cipher )
         {
@@ -1218,6 +1294,7 @@
             correct = 0;
         }
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
         if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
         {
             if( padlen > ssl->transform_in->ivlen )
@@ -1231,6 +1308,10 @@
             }
         }
         else
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_2)
+        if( ssl->minor_ver > SSL_MINOR_VERSION_0 )
         {
             /*
              * TLSv1+: always check the padding up to the first failure
@@ -1254,6 +1335,13 @@
 #endif
             padlen &= correct * 0x1FF;
         }
+        else
+#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \
+          POLARSSL_SSL_PROTO_TLS1_2 */
+        {
+            SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+        }
     }
 
     SSL_DEBUG_BUF( 4, "raw buffer after decryption",
@@ -1269,6 +1357,7 @@
 
     memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen );
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
     if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
     {
         ssl_mac( &ssl->transform_in->md_ctx_dec,
@@ -1277,6 +1366,10 @@
                   ssl->in_ctr, ssl->in_msgtype );
     }
     else
+#endif /* POLARSSL_SSL_PROTO_SSL3 */
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver > SSL_MINOR_VERSION_0 )
     {
         /*
          * Process MAC and always update for padlen afterwards to make
@@ -1307,6 +1400,13 @@
 
         md_hmac_reset( &ssl->transform_in->md_ctx_dec );
     }
+    else
+#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \
+          POLARSSL_SSL_PROTO_TLS1_2 */
+    {
+        SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+    }
 
     SSL_DEBUG_BUF( 4, "message  mac", tmp, ssl->transform_in->maclen );
     SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen,
@@ -1718,13 +1818,17 @@
             return( POLARSSL_ERR_SSL_INVALID_RECORD );
         }
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
         if( ssl->minor_ver == SSL_MINOR_VERSION_0 &&
             ssl->in_msglen > ssl->transform_in->minlen + SSL_MAX_CONTENT_LEN )
         {
             SSL_DEBUG_MSG( 1, ( "bad message length" ) );
             return( POLARSSL_ERR_SSL_INVALID_RECORD );
         }
+#endif
 
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_2)
         /*
          * TLS encrypted messages can have up to 256 bytes of padding
          */
@@ -1734,6 +1838,7 @@
             SSL_DEBUG_MSG( 1, ( "bad message length" ) );
             return( POLARSSL_ERR_SSL_INVALID_RECORD );
         }
+#endif
     }
 
     /*
@@ -1990,6 +2095,7 @@
             return( 0 );
         }
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
         /*
          * If using SSLv3 and got no cert, send an Alert message
          * (otherwise an empty Certificate message will be sent).
@@ -2005,6 +2111,7 @@
             SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) );
             goto write_msg;
         }
+#endif /* POLARSSL_SSL_PROTO_SSL3 */
     }
     else /* SSL_IS_SERVER */
     {
@@ -2055,7 +2162,9 @@
     ssl->out_msgtype = SSL_MSG_HANDSHAKE;
     ssl->out_msg[0]  = SSL_HS_CERTIFICATE;
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
 write_msg:
+#endif
 
     ssl->state++;
 
@@ -2103,6 +2212,7 @@
 
     ssl->state++;
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
     /*
      * Check if the client sent an empty certificate
      */
@@ -2123,7 +2233,10 @@
                 return( POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE );
         }
     }
+#endif /* POLARSSL_SSL_PROTO_SSL3 */
 
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_2)
     if( ssl->endpoint  == SSL_IS_SERVER &&
         ssl->minor_ver != SSL_MINOR_VERSION_0 )
     {
@@ -2141,6 +2254,8 @@
                 return( 0 );
         }
     }
+#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \
+          POLARSSL_SSL_PROTO_TLS1_2 */
 
     if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
     {
@@ -2293,45 +2408,66 @@
 void ssl_optimize_checksum( ssl_context *ssl,
                             const ssl_ciphersuite_t *ciphersuite_info )
 {
-#if !defined(POLARSSL_SHA512_C)
     ((void) ciphersuite_info);
-#endif
 
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
     if( ssl->minor_ver < SSL_MINOR_VERSION_3 )
         ssl->handshake->update_checksum = ssl_update_checksum_md5sha1;
-#if defined(POLARSSL_SHA512_C)
-    else if( ciphersuite_info->mac == POLARSSL_MD_SHA384 )
-    {
-        ssl->handshake->update_checksum = ssl_update_checksum_sha384;
-    }
-#endif
     else
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SHA512_C)
+    if( ciphersuite_info->mac == POLARSSL_MD_SHA384 )
+        ssl->handshake->update_checksum = ssl_update_checksum_sha384;
+    else
+#endif
+#if defined(POLARSSL_SHA256_C)
+    if( ciphersuite_info->mac != POLARSSL_MD_SHA384 )
         ssl->handshake->update_checksum = ssl_update_checksum_sha256;
+    else
+#endif
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
+        /* Should never happen */
+        return;
 }
 
 static void ssl_update_checksum_start( ssl_context *ssl,
                                        const unsigned char *buf, size_t len )
 {
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
      md5_update( &ssl->handshake->fin_md5 , buf, len );
     sha1_update( &ssl->handshake->fin_sha1, buf, len );
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SHA256_C)
     sha256_update( &ssl->handshake->fin_sha256, buf, len );
+#endif
 #if defined(POLARSSL_SHA512_C)
     sha512_update( &ssl->handshake->fin_sha512, buf, len );
 #endif
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 }
 
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
 static void ssl_update_checksum_md5sha1( ssl_context *ssl,
                                          const unsigned char *buf, size_t len )
 {
      md5_update( &ssl->handshake->fin_md5 , buf, len );
     sha1_update( &ssl->handshake->fin_sha1, buf, len );
 }
+#endif
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SHA256_C)
 static void ssl_update_checksum_sha256( ssl_context *ssl,
                                         const unsigned char *buf, size_t len )
 {
     sha256_update( &ssl->handshake->fin_sha256, buf, len );
 }
+#endif
 
 #if defined(POLARSSL_SHA512_C)
 static void ssl_update_checksum_sha384( ssl_context *ssl,
@@ -2340,7 +2476,9 @@
     sha512_update( &ssl->handshake->fin_sha512, buf, len );
 }
 #endif
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
 static void ssl_calc_finished_ssl(
                 ssl_context *ssl, unsigned char *buf, int from )
 {
@@ -2420,7 +2558,9 @@
 
     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
+#endif /* POLARSSL_SSL_PROTO_SSL3 */
 
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1)
 static void ssl_calc_finished_tls(
                 ssl_context *ssl, unsigned char *buf, int from )
 {
@@ -2474,7 +2614,10 @@
 
     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
+#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 */
 
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SHA256_C)
 static void ssl_calc_finished_tls_sha256(
                 ssl_context *ssl, unsigned char *buf, int from )
 {
@@ -2519,6 +2662,7 @@
 
     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
+#endif /* POLARSSL_SHA256_C */
 
 #if defined(POLARSSL_SHA512_C)
 static void ssl_calc_finished_tls_sha384(
@@ -2565,7 +2709,8 @@
 
     SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
 }
-#endif
+#endif /* POLARSSL_SHA512_C */
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
 void ssl_handshake_wrapup( ssl_context *ssl )
 {
@@ -2804,12 +2949,19 @@
     memset( ssl->transform_negotiate, 0, sizeof(ssl_transform) );
     memset( ssl->session_negotiate, 0, sizeof(ssl_session) );
 
+#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_1)
      md5_starts( &ssl->handshake->fin_md5 );
     sha1_starts( &ssl->handshake->fin_sha1 );
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1_2)
+#if defined(POLARSSL_SHA256_C)
     sha256_starts( &ssl->handshake->fin_sha256, 0 );
+#endif
 #if defined(POLARSSL_SHA512_C)
     sha512_starts( &ssl->handshake->fin_sha512, 1 );
 #endif
+#endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
     ssl->handshake->update_checksum = ssl_update_checksum_start;
     ssl->handshake->sig_alg = SSL_HASH_SHA1;
@@ -2834,10 +2986,10 @@
     /*
      * Sane defaults
      */
-    ssl->min_major_ver = SSL_MAJOR_VERSION_3;
-    ssl->min_minor_ver = SSL_MINOR_VERSION_0;
-    ssl->max_major_ver = SSL_MAJOR_VERSION_3;
-    ssl->max_minor_ver = SSL_MINOR_VERSION_3;
+    ssl->min_major_ver = SSL_MIN_MAJOR_VERSION;
+    ssl->min_minor_ver = SSL_MIN_MINOR_VERSION;
+    ssl->max_major_ver = SSL_MAX_MAJOR_VERSION;
+    ssl->max_minor_ver = SSL_MAX_MINOR_VERSION;
 
     ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() );
 
@@ -2881,8 +3033,10 @@
     memset( ssl-> in_ctr, 0, SSL_BUFFER_LEN );
     memset( ssl->out_ctr, 0, SSL_BUFFER_LEN );
 
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
     ssl->hostname = NULL;
     ssl->hostname_len = 0;
+#endif
 
 #if defined(POLARSSL_SSL_SESSION_TICKETS)
     ssl->ticket_lifetime = SSL_DEFAULT_TICKET_LIFETIME;
@@ -3216,6 +3370,7 @@
 }
 #endif /* POLARSSL_DHM_C */
 
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
 int ssl_set_hostname( ssl_context *ssl, const char *hostname )
 {
     if( hostname == NULL )
@@ -3247,17 +3402,26 @@
     ssl->f_sni = f_sni;
     ssl->p_sni = p_sni;
 }
+#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */
 
 void ssl_set_max_version( ssl_context *ssl, int major, int minor )
 {
-    ssl->max_major_ver = major;
-    ssl->max_minor_ver = minor;
+    if( major >= SSL_MIN_MAJOR_VERSION && major <= SSL_MAX_MAJOR_VERSION &&
+        minor >= SSL_MIN_MINOR_VERSION && minor <= SSL_MAX_MINOR_VERSION )
+    {
+        ssl->max_major_ver = major;
+        ssl->max_minor_ver = minor;
+    }
 }
 
 void ssl_set_min_version( ssl_context *ssl, int major, int minor )
 {
-    ssl->min_major_ver = major;
-    ssl->min_minor_ver = minor;
+    if( major >= SSL_MIN_MAJOR_VERSION && major <= SSL_MAX_MAJOR_VERSION &&
+        minor >= SSL_MIN_MINOR_VERSION && minor <= SSL_MAX_MINOR_VERSION )
+    {
+        ssl->min_major_ver = major;
+        ssl->min_minor_ver = minor;
+    }
 }
 
 #if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
@@ -3518,6 +3682,7 @@
             {
                 SSL_DEBUG_MSG( 3, ( "ignoring renegotiation, sending alert" ) );
 
+#if defined(POLARSSL_SSL_PROTO_SSL3)
                 if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
                 {
                     /*
@@ -3527,6 +3692,10 @@
                         return( ret );
                 }
                 else
+#endif
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_2)
+                if( ssl->minor_ver >= SSL_MINOR_VERSION_1 )
                 {
                     if( ( ret = ssl_send_alert_message( ssl,
                                     SSL_ALERT_LEVEL_WARNING,
@@ -3535,6 +3704,12 @@
                         return( ret );
                     }
                 }
+                else
+#endif
+                {
+                    SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                    return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+                }
             }
             else
             {
@@ -3761,12 +3936,14 @@
     polarssl_free( ssl->ticket_keys );
 #endif
 
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
     if ( ssl->hostname != NULL)
     {
         memset( ssl->hostname, 0, ssl->hostname_len );
         polarssl_free( ssl->hostname );
         ssl->hostname_len = 0;
     }
+#endif
 
     if( ssl->pk_key_own_alloc )
     {
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index e5adef7..0650b3a 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -719,7 +719,9 @@
                  strlen( opt.psk_identity ) );
 #endif
 
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
     ssl_set_hostname( &ssl, opt.server_name );
+#endif
 
     if( opt.min_version != -1 )
         ssl_set_min_version( &ssl, SSL_MAJOR_VERSION_3, opt.min_version );
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index 6333d17..cbd1a00 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -596,7 +596,9 @@
     ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
     ssl_set_own_cert( &ssl, &clicert, &pkey );
 
+#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
     ssl_set_hostname( &ssl, opt.server_name );
+#endif
 
     if( opt.mode == MODE_SSL_TLS )
     {
diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function
index 6acf4df..5bfd63d 100644
--- a/tests/suites/test_suite_ecdh.function
+++ b/tests/suites/test_suite_ecdh.function
@@ -3,7 +3,7 @@
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
- * depends_on:POLARSSL_ECDH_C:POLARSSL_ECP_C:POLARSSL_BIGNUM_C
+ * depends_on:POLARSSL_ECDH_C
  * END_DEPENDENCIES
  */
 
diff --git a/tests/suites/test_suite_ecdsa.function b/tests/suites/test_suite_ecdsa.function
index b4d6ffd..5ccb39d 100644
--- a/tests/suites/test_suite_ecdsa.function
+++ b/tests/suites/test_suite_ecdsa.function
@@ -3,7 +3,7 @@
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
- * depends_on:POLARSSL_ECDSA_C:POLARSSL_ECP_C:POLARSSL_BIGNUM_C
+ * depends_on:POLARSSL_ECDSA_C
  * END_DEPENDENCIES
  */
 
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 042077e..62c5de2 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -5,7 +5,7 @@
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
- * depends_on:POLARSSL_ECP_C:POLARSSL_BIGNUM_C
+ * depends_on:POLARSSL_ECP_C
  * END_DEPENDENCIES
  */