Modified to work in-place
diff --git a/library/gcm.c b/library/gcm.c
index 68b6611..7d79f1a 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -193,23 +193,14 @@
     size_t use_len;
     size_t orig_len = length * 8;
     size_t orig_add_len = add_len * 8;
-    unsigned char **xor_p;
 
     memset( y, 0x00, 16 );
     memset( work_buf, 0x00, 16 );
     memset( tag, 0x00, tag_len );
     memset( buf, 0x00, 16 );
 
-    if( ( mode == GCM_DECRYPT && output <= input && ( input - output ) < 8 ) ||
-        ( output > input && (size_t) ( output - input ) < length ) )
-    {
+    if( output > input && (size_t) ( output - input ) < length )
         return( POLARSSL_ERR_GCM_BAD_INPUT );
-    }
-
-    if( mode == GCM_ENCRYPT )
-        xor_p = (unsigned char **) &out_p;
-    else
-        xor_p = (unsigned char **) &p;
 
     if( iv_len == 12 )
     {
@@ -271,8 +262,11 @@
 
         for( i = 0; i < use_len; i++ )
         {
+            if( mode == GCM_DECRYPT )
+                buf[i] ^= p[i];
             out_p[i] = ectr[i] ^ p[i];
-            buf[i] ^= (*xor_p)[i];
+            if( mode == GCM_ENCRYPT )
+                buf[i] ^= out_p[i];
         }
         
         gcm_mult( ctx, buf, buf );