Allow alternate implementation of GCM

Provide the ability to use an alternative implementation of GCM in place
of the library-provided implementation.
diff --git a/ChangeLog b/ChangeLog
index 227faed..d383308 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 mbed TLS ChangeLog (Sorted per branch, date)
 
+= mbed TLS x.x.x branch released xxxx-xx-xx
+
+Features
+   * Add support for alternative implementations of GCM, selected by the
+     configuration flag MBEDTLS_GCM_ALT in config.h
+
 = mbed TLS 2.6.0 branch released 2017-08-10
 
 Security
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 47c7196..94bf0d1 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -267,6 +267,7 @@
 //#define MBEDTLS_BLOWFISH_ALT
 //#define MBEDTLS_CAMELLIA_ALT
 //#define MBEDTLS_DES_ALT
+//#define MBEDTLS_GCM_ALT
 //#define MBEDTLS_XTEA_ALT
 //#define MBEDTLS_MD2_ALT
 //#define MBEDTLS_MD4_ALT
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index 1b77aae..8f3b565 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -33,6 +33,8 @@
 #define MBEDTLS_ERR_GCM_AUTH_FAILED                       -0x0012  /**< Authenticated decryption failed. */
 #define MBEDTLS_ERR_GCM_BAD_INPUT                         -0x0014  /**< Bad input parameters to function. */
 
+#if !defined(MBEDTLS_GCM_ALT)
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -206,6 +208,18 @@
  */
 void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
 
+#ifdef __cplusplus
+}
+#endif
+
+#else  /* !MBEDTLS_GCM_ALT */
+#include "gcm_alt.h"
+#endif /* !MBEDTLS_GCM_ALT */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**
  * \brief          Checkup routine
  *
@@ -217,4 +231,5 @@
 }
 #endif
 
+
 #endif /* gcm.h */
diff --git a/library/gcm.c b/library/gcm.c
index fccb092..2b49fa6 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -54,6 +54,8 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
 
+#if !defined(MBEDTLS_GCM_ALT)
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
@@ -508,6 +510,8 @@
     mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
 }
 
+#endif /* !MBEDTLS_GCM_ALT */
+
 #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
 /*
  * AES-GCM test vectors from:
diff --git a/library/version_features.c b/library/version_features.c
index 5cbe8ac..50afe1e 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -99,6 +99,9 @@
 #if defined(MBEDTLS_DES_ALT)
     "MBEDTLS_DES_ALT",
 #endif /* MBEDTLS_DES_ALT */
+#if defined(MBEDTLS_GCM_ALT)
+    "MBEDTLS_GCM_ALT",
+#endif /* MBEDTLS_GCM_ALT */
 #if defined(MBEDTLS_XTEA_ALT)
     "MBEDTLS_XTEA_ALT",
 #endif /* MBEDTLS_XTEA_ALT */