Skip MAC computation/check when GCM is used
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 6164a41..b1e5021 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -973,41 +973,53 @@
     SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
 
     /*
-     * Add MAC then encrypt
+     * Add MAC before encrypt, except for GCM
      */
-#if defined(POLARSSL_SSL_PROTO_SSL3)
-    if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
+#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) ||     \
+    ( defined(POLARSSL_CIPHER_MODE_CBC) &&                                  \
+      ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) ) )
+    if( ssl->transform_out->cipher_ctx_enc.cipher_info->mode !=
+                                                        POLARSSL_MODE_GCM )
     {
-        ssl_mac( &ssl->transform_out->md_ctx_enc,
-                  ssl->transform_out->mac_enc,
-                  ssl->out_msg, ssl->out_msglen,
-                  ssl->out_ctr, ssl->out_msgtype );
-    }
-    else
+#if defined(POLARSSL_SSL_PROTO_SSL3)
+        if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
+        {
+            ssl_mac( &ssl->transform_out->md_ctx_enc,
+                      ssl->transform_out->mac_enc,
+                      ssl->out_msg, ssl->out_msglen,
+                      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,
-                         ssl->out_msg, ssl->out_msglen );
-        md_hmac_finish( &ssl->transform_out->md_ctx_enc,
-                         ssl->out_msg + ssl->out_msglen );
-        md_hmac_reset( &ssl->transform_out->md_ctx_enc );
-    }
-    else
+        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,
+                             ssl->out_msg, ssl->out_msglen );
+            md_hmac_finish( &ssl->transform_out->md_ctx_enc,
+                             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_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 );
+
+        ssl->out_msglen += ssl->transform_out->maclen;
     }
+#endif /* GCM not the only option */
 
-    SSL_DEBUG_BUF( 4, "computed mac",
-                   ssl->out_msg + ssl->out_msglen, ssl->transform_out->maclen );
-
-    ssl->out_msglen += ssl->transform_out->maclen;
-
+    /*
+     * Encrypt
+     */
 #if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER)
     if( ssl->transform_out->cipher_ctx_enc.cipher_info->mode ==
                                                         POLARSSL_MODE_STREAM )
@@ -1634,84 +1646,92 @@
                    ssl->in_msg, ssl->in_msglen );
 
     /*
-     * Always compute the MAC (RFC4346, CBCTIME).
+     * Always compute the MAC (RFC4346, CBCTIME), except for GCM of course
      */
-    ssl->in_msglen -= ( ssl->transform_in->maclen + padlen );
+#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) ||     \
+    ( defined(POLARSSL_CIPHER_MODE_CBC) &&                                  \
+      ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) ) )
+    if( ssl->transform_in->cipher_ctx_dec.cipher_info->mode !=
+                                                        POLARSSL_MODE_GCM )
+    {
+        ssl->in_msglen -= ( ssl->transform_in->maclen + padlen );
 
-    ssl->in_hdr[3] = (unsigned char)( ssl->in_msglen >> 8 );
-    ssl->in_hdr[4] = (unsigned char)( ssl->in_msglen      );
+        ssl->in_hdr[3] = (unsigned char)( ssl->in_msglen >> 8 );
+        ssl->in_hdr[4] = (unsigned char)( ssl->in_msglen      );
 
-    memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen );
+        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,
-                  ssl->transform_in->mac_dec,
-                  ssl->in_msg, ssl->in_msglen,
-                  ssl->in_ctr, ssl->in_msgtype );
-    }
-    else
+        if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
+        {
+            ssl_mac( &ssl->transform_in->md_ctx_dec,
+                      ssl->transform_in->mac_dec,
+                      ssl->in_msg, ssl->in_msglen,
+                      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
-         * total time independent of padlen
-         *
-         * extra_run compensates MAC check for padlen 
-         *
-         * Known timing attacks:
-         *  - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
-         *
-         * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values
-         * correctly. (We round down instead of up, so -56 is the correct
-         * value for our calculations instead of -55)
-         */
-        size_t j, extra_run = 0;
-        extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
-                    ( 13 + ssl->in_msglen          + 8 ) / 64;
+        defined(POLARSSL_SSL_PROTO_TLS1_2)
+        if( ssl->minor_ver > SSL_MINOR_VERSION_0 )
+        {
+            /*
+             * Process MAC and always update for padlen afterwards to make
+             * total time independent of padlen
+             *
+             * extra_run compensates MAC check for padlen 
+             *
+             * Known timing attacks:
+             *  - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
+             *
+             * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values
+             * correctly. (We round down instead of up, so -56 is the correct
+             * value for our calculations instead of -55)
+             */
+            size_t j, extra_run = 0;
+            extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
+                        ( 13 + ssl->in_msglen          + 8 ) / 64;
 
-        extra_run &= correct * 0xFF;
+            extra_run &= correct * 0xFF;
 
-        md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 13 );
-        md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
-                         ssl->in_msglen );
-        md_hmac_finish( &ssl->transform_in->md_ctx_dec,
-                         ssl->in_msg + ssl->in_msglen );
-        for( j = 0; j < extra_run; j++ )
-            md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
+            md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 13 );
+            md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
+                             ssl->in_msglen );
+            md_hmac_finish( &ssl->transform_in->md_ctx_dec,
+                             ssl->in_msg + ssl->in_msglen );
+            for( j = 0; j < extra_run; j++ )
+                md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
 
-        md_hmac_reset( &ssl->transform_in->md_ctx_dec );
-    }
-    else
+            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 );
-    }
+              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,
-                   ssl->transform_in->maclen );
+        SSL_DEBUG_BUF( 4, "message  mac", tmp, ssl->transform_in->maclen );
+        SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen,
+                       ssl->transform_in->maclen );
 
-    if( memcmp( tmp, ssl->in_msg + ssl->in_msglen,
-                     ssl->transform_in->maclen ) != 0 )
-    {
+        if( memcmp( tmp, ssl->in_msg + ssl->in_msglen,
+                         ssl->transform_in->maclen ) != 0 )
+        {
 #if defined(POLARSSL_SSL_DEBUG_ALL)
-        SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
+            SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
 #endif
-        correct = 0;
-    }
+            correct = 0;
+        }
 
-    /*
-     * Finally check the correct flag
-     */
-    if( correct == 0 )
-        return( POLARSSL_ERR_SSL_INVALID_MAC );
+        /*
+         * Finally check the correct flag
+         */
+        if( correct == 0 )
+            return( POLARSSL_ERR_SSL_INVALID_MAC );
+    }
+#endif /* GCM not the only option */
 
     if( ssl->in_msglen == 0 )
     {