Add output parameter to mbedtls_gcm_finish

Alternative implementations of GCM may delay the output of partial
blocks from mbedtls_gcm_update(). Add an output parameter to
mbedtls_gcm_finish() to allow such implementations to pass the final
partial block back to the caller. With the software implementation,
this final output is always empty.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/library/cipher.c b/library/cipher.c
index c88d666..63eaba8 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -1101,6 +1101,7 @@
 #if defined(MBEDTLS_GCM_C)
     if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
         return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
+                                    NULL, 0,
                                     tag, tag_len ) );
 #endif
 
@@ -1153,6 +1154,7 @@
 
         if( 0 != ( ret = mbedtls_gcm_finish(
                        (mbedtls_gcm_context *) ctx->cipher_ctx,
+                       NULL, 0,
                        check_tag, tag_len ) ) )
         {
             return( ret );
diff --git a/library/gcm.c b/library/gcm.c
index b3105d8..de766bc 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -471,8 +471,8 @@
 }
 
 int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
-                unsigned char *tag,
-                size_t tag_len )
+                        unsigned char *output, size_t output_len,
+                        unsigned char *tag, size_t tag_len )
 {
     unsigned char work_buf[16];
     size_t i;
@@ -482,6 +482,11 @@
     GCM_VALIDATE_RET( ctx != NULL );
     GCM_VALIDATE_RET( tag != NULL );
 
+    /* We never pass any output in finish(). The output parameter exists only
+     * for the sake of alternative implementations. */
+    (void) output;
+    (void) output_len;
+
     orig_len = ctx->len * 8;
     orig_add_len = ctx->add_len * 8;
 
@@ -541,7 +546,7 @@
     if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
         return( ret );
 
-    if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
+    if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, tag, tag_len ) ) != 0 )
         return( ret );
 
     return( 0 );
@@ -979,7 +984,7 @@
                     goto exit;
             }
 
-            ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
+            ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
             if( ret != 0 )
                 goto exit;
 
@@ -1039,7 +1044,7 @@
                     goto exit;
             }
 
-            ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
+            ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
             if( ret != 0 )
                 goto exit;