Merged new cipher layer enhancements
diff --git a/include/polarssl/arc4.h b/include/polarssl/arc4.h
index aa8feaa..9333265 100644
--- a/include/polarssl/arc4.h
+++ b/include/polarssl/arc4.h
@@ -55,7 +55,7 @@
  *
  * \param ctx      ARC4 context to be initialized
  * \param key      the secret key
- * \param keylen   length of the key
+ * \param keylen   length of the key, in bytes
  */
 void arc4_setup( arc4_context *ctx, const unsigned char *key, unsigned int keylen );
 
diff --git a/include/polarssl/cipher.h b/include/polarssl/cipher.h
index ef037be..cc69208 100644
--- a/include/polarssl/cipher.h
+++ b/include/polarssl/cipher.h
@@ -30,6 +30,12 @@
 #ifndef POLARSSL_CIPHER_H
 #define POLARSSL_CIPHER_H
 
+#include "config.h"
+
+#if defined(POLARSSL_GCM_C)
+#define POLARSSL_CIPHER_MODE_AEAD
+#endif
+
 #include <string.h>
 
 #if defined(_MSC_VER) && !defined(inline)
@@ -74,6 +80,7 @@
     POLARSSL_CIPHER_AES_192_CTR,
     POLARSSL_CIPHER_AES_256_CTR,
     POLARSSL_CIPHER_AES_128_GCM,
+    POLARSSL_CIPHER_AES_192_GCM,
     POLARSSL_CIPHER_AES_256_GCM,
     POLARSSL_CIPHER_CAMELLIA_128_CBC,
     POLARSSL_CIPHER_CAMELLIA_192_CBC,
@@ -185,9 +192,13 @@
     /** Name of the cipher */
     const char * name;
 
-    /** IV size, in bytes */
+    /** IV/NONCE size, in bytes.
+     *  For cipher that accept many sizes: recommended size */
     unsigned int iv_size;
 
+    /** Flag for ciphers that accept many sizes of IV/NONCE */
+    int accepts_variable_iv_size;
+
     /** block size, in bytes */
     unsigned int block_size;
 
@@ -222,6 +233,9 @@
     /** Current IV or NONCE_COUNTER for CTR-mode */
     unsigned char iv[POLARSSL_MAX_IV_LENGTH];
 
+    /** IV size in bytes (for ciphers with variable-length IVs) */
+    size_t iv_size;
+
     /** Cipher-specific context */
     void *cipher_ctx;
 } cipher_context_t;
@@ -315,18 +329,22 @@
 }
 
 /**
- * \brief               Returns the size of the cipher's IV.
+ * \brief               Returns the size of the cipher's IV/NONCE in bytes.
  *
  * \param ctx           cipher's context. Must have been initialised.
  *
- * \return              size of the cipher's IV, or 0 if ctx has not been
- *                      initialised or accepts IV of various sizes.
+ * \return              If IV has not been set yet: (recommended) IV size
+ *                      (0 for ciphers not using IV/NONCE).
+ *                      If IV has already been set: actual size.
  */
 static inline int cipher_get_iv_size( const cipher_context_t *ctx )
 {
     if( NULL == ctx || NULL == ctx->cipher_info )
         return 0;
 
+    if( ctx->iv_size != 0 )
+        return ctx->iv_size;
+
     return ctx->cipher_info->iv_size;
 }
 
@@ -428,22 +446,49 @@
 int cipher_set_padding_mode( cipher_context_t *ctx, cipher_padding_t mode );
 
 /**
- * \brief               Reset the given context, setting the IV to iv
+ * \brief               Set the initialization vector (IV) or nonce
+ *
+ * \param iv            IV to use (or NONCE_COUNTER for CTR-mode ciphers)
+ * \param iv_len        IV length for ciphers with variable-size IV;
+ *                      discarded by ciphers with fixed-size IV.
+ *
+ * \returns             O on success, or POLARSSL_ERR_CIPHER_BAD_INPUT_DATA
+ *
+ * \note                Some ciphers don't use IVs nor NONCE. For these
+ *                      ciphers, this function has no effect.
+ */
+int cipher_set_iv( cipher_context_t *ctx,
+                   const unsigned char *iv, size_t iv_len );
+
+/**
+ * \brief               Finish preparation of the given context
  *
  * \param ctx           generic cipher context
- * \param iv            IV to use or NONCE_COUNTER in the case of a CTR-mode cipher
- * \param iv_len        IV length for ciphers with variable-size IV,
- *                      Discared by ciphers with fixed-size IV.
- * \param ad            Additional data for AEAD ciphers, or discarded.
- *                      May be NULL only if ad_len is 0.
- * \param ad_len        Length of ad for AEAD ciphers, or discarded.
  *
  * \returns             0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA
  *                      if parameter verification fails.
  */
-int cipher_reset( cipher_context_t *ctx,
-                  const unsigned char *iv, size_t iv_len,
-                  const unsigned char *ad, size_t ad_len );
+int cipher_reset( cipher_context_t *ctx );
+
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+/**
+ * \brief               Add additional data (for AEAD ciphers).
+ *                      This function has no effect for non-AEAD ciphers.
+ *                      For AEAD ciphers, it may or may not be called
+ *                      repeatedly, and/or interleaved with calls to
+ *                      cipher_udpate(), depending on the cipher.
+ *                      E.g. for GCM is must be called exactly once, right
+ *                      after cipher_reset().
+ *
+ * \param ctx           generic cipher context
+ * \param ad            Additional data to use.
+ * \param ad_len        Length of ad.
+ *
+ * \returns             0 on success, or a specific error code.
+ */
+int cipher_update_ad( cipher_context_t *ctx,
+                      const unsigned char *ad, size_t ad_len );
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
 
 /**
  * \brief               Generic cipher update function. Encrypts/decrypts
@@ -480,11 +525,6 @@
  * \param ctx           Generic cipher context
  * \param output        buffer to write data to. Needs block_size available.
  * \param olen          length of the data written to the output buffer.
- * \param tag           Ignore by non-AEAD ciphers. For AEAD ciphers:
- *                      - on encryption: buffer to write the tag;
- *                      - on decryption: tag to verify.
- *                      May be NULL if tag_len is zero.
- * \param tag_len       Length of the tag to write/check for AEAD ciphers.
  *
  * \returns             0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if
  *                      parameter verification fails,
@@ -494,8 +534,36 @@
  *                      while decrypting or a cipher specific error code.
  */
 int cipher_finish( cipher_context_t *ctx,
-                   unsigned char *output, size_t *olen,
-                   unsigned char *tag, size_t tag_len );
+                   unsigned char *output, size_t *olen );
+
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+/**
+ * \brief               Write tag for AEAD ciphers.
+ *                      No effect for other ciphers.
+ *                      Must be called after cipher_finish().
+ *
+ * \param tag           buffer to write the tag
+ * \param tag_len       Length of the tag to write
+ *
+ * \return              0 on success, or a specific error code.
+ */
+int cipher_write_tag( cipher_context_t *ctx,
+                      unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief               Check tag for AEAD ciphers.
+ *                      No effect for other ciphers.
+ *                      Calling time depends on the cipher:
+ *                      for GCM, must be called after cipher_finish().
+ *
+ * \param tag           Buffer holding the tag
+ * \param tag_len       Length of the tag to check
+ *
+ * \return              0 on success, or a specific error code.
+ */
+int cipher_check_tag( cipher_context_t *ctx,
+                      const unsigned char *tag, size_t tag_len );
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
 
 /**
  * \brief          Checkup routine
diff --git a/include/polarssl/cipher_wrap.h b/include/polarssl/cipher_wrap.h
index 4dabb44..8485256 100644
--- a/include/polarssl/cipher_wrap.h
+++ b/include/polarssl/cipher_wrap.h
@@ -56,6 +56,7 @@
 
 #if defined(POLARSSL_GCM_C)
 extern const cipher_info_t aes_128_gcm_info;
+extern const cipher_info_t aes_192_gcm_info;
 extern const cipher_info_t aes_256_gcm_info;
 #endif /* POLARSSL_GCM_C */
 
diff --git a/library/cipher.c b/library/cipher.c
index d7cac05..a014eca 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -67,6 +67,12 @@
         POLARSSL_CIPHER_AES_256_CTR,
 #endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
 
+#if defined(POLARSSL_GCM_C)
+        POLARSSL_CIPHER_AES_128_GCM,
+        POLARSSL_CIPHER_AES_192_GCM,
+        POLARSSL_CIPHER_AES_256_GCM,
+#endif /* defined(POLARSSL_GCM_C) */
+
 #endif /* defined(POLARSSL_AES_C) */
 
 #if defined(POLARSSL_ARC4_C)
@@ -157,6 +163,8 @@
 #if defined(POLARSSL_GCM_C)
         case POLARSSL_CIPHER_AES_128_GCM:
             return &aes_128_gcm_info;
+        case POLARSSL_CIPHER_AES_192_GCM:
+            return &aes_192_gcm_info;
         case POLARSSL_CIPHER_AES_256_GCM:
             return &aes_256_gcm_info;
 #endif /* defined(POLARSSL_GCM_C) */
@@ -293,6 +301,8 @@
 #if defined(POLARSSL_GCM_C)
     if( !strcasecmp( "AES-128-GCM", cipher_name ) )
         return cipher_info_from_type( POLARSSL_CIPHER_AES_128_GCM );
+    if( !strcasecmp( "AES-192-GCM", cipher_name ) )
+        return cipher_info_from_type( POLARSSL_CIPHER_AES_192_GCM );
     if( !strcasecmp( "AES-256-GCM", cipher_name ) )
         return cipher_info_from_type( POLARSSL_CIPHER_AES_256_GCM );
 #endif
@@ -396,31 +406,60 @@
     return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
 }
 
-int cipher_reset( cipher_context_t *ctx,
-                  const unsigned char *iv, size_t iv_len,
-                  const unsigned char *ad, size_t ad_len )
+int cipher_set_iv( cipher_context_t *ctx,
+                   const unsigned char *iv, size_t iv_len )
 {
+    size_t actual_iv_size;
+
     if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
         return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
 
+    if( ctx->cipher_info->accepts_variable_iv_size )
+        actual_iv_size = iv_len;
+    else
+        actual_iv_size = ctx->cipher_info->iv_size;
+
+    memcpy( ctx->iv, iv, actual_iv_size );
+    ctx->iv_size = actual_iv_size;
+
+    return 0;
+}
+
+int cipher_reset( cipher_context_t *ctx )
+{
+    if( NULL == ctx || NULL == ctx->cipher_info )
+        return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
+
     ctx->unprocessed_len = 0;
 
+    return 0;
+}
+
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+int cipher_update_ad( cipher_context_t *ctx,
+                      const unsigned char *ad, size_t ad_len )
+{
+    if( NULL == ctx || NULL == ctx->cipher_info )
+        return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
+
 #if defined(POLARSSL_GCM_C)
     if( POLARSSL_MODE_GCM == ctx->cipher_info->mode )
     {
-        return gcm_starts( ctx->cipher_ctx, ctx->operation,
-                           iv, iv_len, ad, ad_len );
-    }
-#else
-    ((void) ad);
-    ((void) ad_len);
-    ((void) iv_len);
-#endif
+        /* Make sure we're called right after cipher_reset() */
+        if( ((gcm_context *) ctx->cipher_ctx)->len != 0 ||
+            ((gcm_context *) ctx->cipher_ctx)->add_len != 0 )
+        {
+            return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
+        }
 
-    memcpy( ctx->iv, iv, cipher_get_iv_size( ctx ) );
+        return gcm_starts( ctx->cipher_ctx, ctx->operation,
+                           ctx->iv, ctx->iv_size, ad, ad_len );
+    }
+#endif
 
     return 0;
 }
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
 
 int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ilen,
         unsigned char *output, size_t *olen )
@@ -747,8 +786,7 @@
 }
 
 int cipher_finish( cipher_context_t *ctx,
-                   unsigned char *output, size_t *olen,
-                   unsigned char *tag, size_t tag_len )
+                   unsigned char *output, size_t *olen )
 {
     int ret = 0;
 
@@ -767,10 +805,6 @@
 #if defined(POLARSSL_GCM_C)
     if( POLARSSL_MODE_GCM == ctx->cipher_info->mode )
     {
-        unsigned char check_tag[16];
-        size_t i;
-        int diff;
-
         if( 0 != ( ret = gcm_update( ctx->cipher_ctx,
                         ctx->unprocessed_len, ctx->unprocessed_data,
                         output ) ) )
@@ -780,29 +814,8 @@
 
         *olen += ctx->unprocessed_len;
 
-        if( 0 != ( ret = gcm_finish( ctx->cipher_ctx, check_tag, tag_len ) ) )
-            return( ret );
-
-        /* On encryption, write the tag */
-        if( POLARSSL_ENCRYPT == ctx->operation )
-        {
-            if( tag_len != 0 )
-                memcpy( tag, check_tag, tag_len );
-            return( 0 );
-        }
-
-        /* On decryption, check the tag (in "constant-time") */
-        for( diff = 0, i = 0; i < tag_len; i++ )
-            diff |= tag[i] ^ check_tag[i];
-
-        if( diff != 0 )
-            return( POLARSSL_ERR_GCM_AUTH_FAILED );
-
         return( 0 );
     }
-#else
-    ((void) tag);
-    ((void) tag_len);
 #endif
 
     if( POLARSSL_MODE_CBC == ctx->cipher_info->mode )
@@ -900,6 +913,63 @@
     return 0;
 }
 
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+int cipher_write_tag( cipher_context_t *ctx,
+                      unsigned char *tag, size_t tag_len )
+{
+    if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag )
+        return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
+
+    if( POLARSSL_ENCRYPT != ctx->operation )
+        return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
+
+#if defined(POLARSSL_GCM_C)
+    if( POLARSSL_MODE_GCM == ctx->cipher_info->mode )
+        return gcm_finish( ctx->cipher_ctx, tag, tag_len );
+#endif
+
+    return 0;
+}
+ 
+int cipher_check_tag( cipher_context_t *ctx,
+                      const unsigned char *tag, size_t tag_len )
+{
+    int ret;
+
+    if( NULL == ctx || NULL == ctx->cipher_info ||
+        POLARSSL_DECRYPT != ctx->operation )
+    {
+        return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
+    }
+
+#if defined(POLARSSL_GCM_C)
+    if( POLARSSL_MODE_GCM == ctx->cipher_info->mode )
+    {
+        unsigned char check_tag[16];
+        size_t i;
+        int diff;
+
+        if( tag_len > sizeof( check_tag ) )
+            return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
+
+        if( 0 != ( ret = gcm_finish( ctx->cipher_ctx, check_tag, tag_len ) ) )
+            return( ret );
+
+        /* Check the tag in "constant-time" */
+        for( diff = 0, i = 0; i < tag_len; i++ )
+            diff |= tag[i] ^ check_tag[i];
+
+        if( diff != 0 )
+            return( POLARSSL_ERR_GCM_AUTH_FAILED );
+
+        return( 0 );
+    }
+#endif
+
+    return( 0 );
+}
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
+
 #if defined(POLARSSL_SELF_TEST)
 
 #include <stdio.h>
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index 5c98100..f09823a 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -150,6 +150,7 @@
     128,
     "AES-128-CBC",
     16,
+    0,
     16,
     &aes_info
 };
@@ -160,6 +161,7 @@
     192,
     "AES-192-CBC",
     16,
+    0,
     16,
     &aes_info
 };
@@ -170,6 +172,7 @@
     256,
     "AES-256-CBC",
     16,
+    0,
     16,
     &aes_info
 };
@@ -181,6 +184,7 @@
     128,
     "AES-128-CFB128",
     16,
+    0,
     16,
     &aes_info
 };
@@ -191,6 +195,7 @@
     192,
     "AES-192-CFB128",
     16,
+    0,
     16,
     &aes_info
 };
@@ -201,6 +206,7 @@
     256,
     "AES-256-CFB128",
     16,
+    0,
     16,
     &aes_info
 };
@@ -213,6 +219,7 @@
     128,
     "AES-128-CTR",
     16,
+    0,
     16,
     &aes_info
 };
@@ -223,6 +230,7 @@
     192,
     "AES-192-CTR",
     16,
+    0,
     16,
     &aes_info
 };
@@ -233,6 +241,7 @@
     256,
     "AES-256-CTR",
     16,
+    0,
     16,
     &aes_info
 };
@@ -271,7 +280,19 @@
     POLARSSL_MODE_GCM,
     128,
     "AES-128-GCM",
-    0,
+    12,
+    1,
+    16,
+    &gcm_aes_info
+};
+
+const cipher_info_t aes_192_gcm_info = {
+    POLARSSL_CIPHER_AES_192_GCM,
+    POLARSSL_MODE_GCM,
+    192,
+    "AES-192-GCM",
+    12,
+    1,
     16,
     &gcm_aes_info
 };
@@ -281,7 +302,8 @@
     POLARSSL_MODE_GCM,
     256,
     "AES-256-GCM",
-    0,
+    12,
+    1,
     16,
     &gcm_aes_info
 };
@@ -373,6 +395,7 @@
     128,
     "CAMELLIA-128-CBC",
     16,
+    0,
     16,
     &camellia_info
 };
@@ -383,6 +406,7 @@
     192,
     "CAMELLIA-192-CBC",
     16,
+    0,
     16,
     &camellia_info
 };
@@ -393,6 +417,7 @@
     256,
     "CAMELLIA-256-CBC",
     16,
+    0,
     16,
     &camellia_info
 };
@@ -404,6 +429,7 @@
     128,
     "CAMELLIA-128-CFB128",
     16,
+    0,
     16,
     &camellia_info
 };
@@ -414,6 +440,7 @@
     192,
     "CAMELLIA-192-CFB128",
     16,
+    0,
     16,
     &camellia_info
 };
@@ -424,6 +451,7 @@
     256,
     "CAMELLIA-256-CFB128",
     16,
+    0,
     16,
     &camellia_info
 };
@@ -436,6 +464,7 @@
     128,
     "CAMELLIA-128-CTR",
     16,
+    0,
     16,
     &camellia_info
 };
@@ -446,6 +475,7 @@
     192,
     "CAMELLIA-192-CTR",
     16,
+    0,
     16,
     &camellia_info
 };
@@ -456,6 +486,7 @@
     256,
     "CAMELLIA-256-CTR",
     16,
+    0,
     16,
     &camellia_info
 };
@@ -581,6 +612,7 @@
     POLARSSL_KEY_LENGTH_DES,
     "DES-CBC",
     8,
+    0,
     8,
     &des_info
 };
@@ -603,6 +635,7 @@
     POLARSSL_KEY_LENGTH_DES_EDE,
     "DES-EDE-CBC",
     8,
+    0,
     8,
     &des_ede_info
 };
@@ -625,6 +658,7 @@
     POLARSSL_KEY_LENGTH_DES_EDE3,
     "DES-EDE3-CBC",
     8,
+    0,
     8,
     &des_ede3_info
 };
@@ -709,6 +743,7 @@
     128,
     "BLOWFISH-CBC",
     8,
+    0,
     8,
     &blowfish_info
 };
@@ -720,6 +755,7 @@
     128,
     "BLOWFISH-CFB64",
     8,
+    0,
     8,
     &blowfish_info
 };
@@ -732,6 +768,7 @@
     128,
     "BLOWFISH-CTR",
     8,
+    0,
     8,
     &blowfish_info
 };
@@ -749,7 +786,11 @@
 static int arc4_setkey_wrap( void *ctx, const unsigned char *key,
                              unsigned int key_length )
 {
-    arc4_setup( (arc4_context *) ctx, key, key_length );
+    /* we get key_length in bits, arc4 expects it in bytes */
+    if( key_length % 8 != 0)
+        return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
+
+    arc4_setup( (arc4_context *) ctx, key, key_length / 8 );
     return( 0 );
 }
 
@@ -781,6 +822,7 @@
     128,
     "ARC4-128",
     0,
+    0,
     1,
     &arc4_base_info
 };
@@ -834,6 +876,7 @@
     0,
     "NULL",
     0,
+    0,
     1,
     &null_base_info
 };
diff --git a/library/pkcs12.c b/library/pkcs12.c
index 9ccb60a..335af7e 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -184,7 +184,10 @@
     if( ( ret = cipher_setkey( &cipher_ctx, key, keylen, mode ) ) != 0 )
         goto exit;
 
-    if( ( ret = cipher_reset( &cipher_ctx, iv, 0, NULL, 0 ) ) != 0 )
+    if( ( ret = cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 )
+        goto exit;
+
+    if( ( ret = cipher_reset( &cipher_ctx ) ) != 0 )
         goto exit;
 
     if( ( ret = cipher_update( &cipher_ctx, data, len,
@@ -193,11 +196,8 @@
         goto exit;
     }
 
-    if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen, NULL, 0 ) )
-                != 0 )
-    {
+    if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
         ret = POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH;
-    }
 
 exit:
     cipher_free_ctx( &cipher_ctx );
diff --git a/library/pkcs5.c b/library/pkcs5.c
index 2b6a75a..0b9830d 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -187,7 +187,10 @@
     if( ( ret = cipher_setkey( &cipher_ctx, key, keylen, mode ) ) != 0 )
         goto exit;
 
-    if( ( ret = cipher_reset( &cipher_ctx, iv, 0, NULL, 0 ) ) != 0 )
+    if( ( ret = cipher_set_iv( &cipher_ctx, iv, enc_scheme_params.len ) ) != 0 )
+        goto exit;
+
+    if( ( ret = cipher_reset( &cipher_ctx ) ) != 0 )
         goto exit;
 
     if( ( ret = cipher_update( &cipher_ctx, data, datalen,
@@ -196,11 +199,8 @@
         goto exit;
     }
 
-    if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen, NULL, 0 ) )
-                != 0 )
-    {
+    if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
         ret = POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH;
-    }
 
 exit:
     md_free_ctx( &md_ctx );
diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c
index a9b862e..6caaad8 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -306,7 +306,12 @@
             fprintf( stderr, "cipher_setkey() returned error\n");
             goto exit;
         }
-        if( cipher_reset( &cipher_ctx, IV, 16, NULL, 0 ) != 0 )
+        if( cipher_set_iv( &cipher_ctx, IV, 16 ) != 0 )
+        {
+            fprintf( stderr, "cipher_set_iv() returned error\n");
+            goto exit;
+        }
+        if( cipher_reset( &cipher_ctx ) != 0 )
         {
             fprintf( stderr, "cipher_reset() returned error\n");
             goto exit;
@@ -338,7 +343,7 @@
             }
         }
 
-        if( cipher_finish( &cipher_ctx, output, &olen, NULL, 0 ) != 0 )
+        if( cipher_finish( &cipher_ctx, output, &olen ) != 0 )
         {
             fprintf( stderr, "cipher_finish() returned error\n" );
             goto exit;
@@ -424,7 +429,8 @@
 
         cipher_setkey( &cipher_ctx, digest, cipher_info->key_length,
             POLARSSL_DECRYPT );
-        cipher_reset( &cipher_ctx, IV, 16, NULL, 0 );
+        cipher_set_iv( &cipher_ctx, IV, 16 );
+        cipher_reset( &cipher_ctx );
 
         md_hmac_starts( &md_ctx, digest, 32 );
 
@@ -455,7 +461,7 @@
         /*
          * Write the final block of data
          */
-        cipher_finish( &cipher_ctx, output, &olen, NULL, 0 );
+        cipher_finish( &cipher_ctx, output, &olen );
 
         if( fwrite( output, 1, olen, fout ) != olen )
         {
diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data
index 2e45ae4..fc0beac 100644
--- a/tests/suites/test_suite_cipher.aes.data
+++ b/tests/suites/test_suite_cipher.aes.data
@@ -764,3 +764,31 @@
 AES Encrypt and decrypt 32 bytes in multiple parts 1
 depends_on:POLARSSL_AES_C
 enc_dec_buf_multipart:POLARSSL_CIPHER_AES_256_CBC:256:16:16:
+
+AES Decrypt test vector #0
+depends_on:POLARSSL_AES_C:POLARSSL_CIPHER_PADDING_PKCS7
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_CBC:POLARSSL_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"00000000000000000000000000000000":"":"":POLARSSL_ERR_CIPHER_INVALID_PADDING:0
+
+AES Decrypt test vector #1
+depends_on:POLARSSL_AES_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_CBC:POLARSSL_PADDING_NONE:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"00000000000000000000000000000000":"":"":0:0
+
+AES Decrypt test vector #2
+depends_on:POLARSSL_AES_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_192_CBC:POLARSSL_PADDING_NONE:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"fffffffff80000000000000000000000":"":"":0:0
+
+AES Decrypt test vector #3
+depends_on:POLARSSL_AES_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_256_CBC:POLARSSL_PADDING_NONE:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"ff000000000000000000000000000000":"":"":0:0
+
+AES Decrypt test vector #4
+depends_on:POLARSSL_AES_C:POLARSSL_CIPHER_MODE_CFB
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_CFB128:-1:"fffffffe000000000000000000000000":"00000000000000000000000000000000":"1114bc2028009b923f0b01915ce5e7c4":"00000000000000000000000000000000":"":"":0:0:
+
+AES Decrypt test vector #5
+depends_on:POLARSSL_AES_C:POLARSSL_CIPHER_MODE_CFB
+decrypt_test_vec:POLARSSL_CIPHER_AES_192_CFB128:-1:"ffffffffffffffffffffffffffffffffffffffffffe00000":"00000000000000000000000000000000":"60136703374f64e860b48ce31f930716":"00000000000000000000000000000000":"":"":0:0
+
+AES Decrypt test vector #6
+depends_on:POLARSSL_AES_C:POLARSSL_CIPHER_MODE_CFB
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_CFB128:-1:"ffffffffff800000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"be66cfea2fecd6bf0ec7b4352c99bcaa":"00000000000000000000000000000000":"":"":0:0
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index b1814fa..c556a2e 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -1,5 +1,9 @@
 /* BEGIN_HEADER */
 #include <polarssl/cipher.h>
+
+#if defined(POLARSSL_GCM_C)
+#include <polarssl/gcm.h>
+#endif
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -58,8 +62,16 @@
         TEST_ASSERT( 0 == cipher_set_padding_mode( &ctx_enc, pad_mode ) );
     }
 
-    TEST_ASSERT( 0 == cipher_reset( &ctx_dec, iv, 16, ad, 13 ) );
-    TEST_ASSERT( 0 == cipher_reset( &ctx_enc, iv, 16, ad, 13 ) );
+    TEST_ASSERT( 0 == cipher_set_iv( &ctx_dec, iv, 16 ) );
+    TEST_ASSERT( 0 == cipher_set_iv( &ctx_enc, iv, 16 ) );
+
+    TEST_ASSERT( 0 == cipher_reset( &ctx_dec ) );
+    TEST_ASSERT( 0 == cipher_reset( &ctx_enc ) );
+
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+    TEST_ASSERT( 0 == cipher_update_ad( &ctx_dec, ad, 13 ) );
+    TEST_ASSERT( 0 == cipher_update_ad( &ctx_enc, ad, 13 ) );
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
 
     /* encode length number of bytes from inbuf */
     TEST_ASSERT( 0 == cipher_update( &ctx_enc, inbuf, length, encbuf, &outlen ) );
@@ -70,10 +82,13 @@
                    total_len < length &&
                    total_len + cipher_get_block_size( &ctx_enc ) > length ) );
 
-    TEST_ASSERT( 0 == cipher_finish( &ctx_enc, encbuf + outlen, &outlen,
-                                     tag, 16 ) );
+    TEST_ASSERT( 0 == cipher_finish( &ctx_enc, encbuf + outlen, &outlen ) );
     total_len += outlen;
 
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+    TEST_ASSERT( 0 == cipher_write_tag( &ctx_enc, tag, 16 ) );
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
+
     TEST_ASSERT( total_len == length ||
                  ( total_len % cipher_get_block_size( &ctx_enc ) == 0 &&
                    total_len > length &&
@@ -88,10 +103,13 @@
                    total_len < length &&
                    total_len + cipher_get_block_size( &ctx_dec ) >= length ) );
 
-    TEST_ASSERT( 0 == cipher_finish( &ctx_dec, decbuf + outlen, &outlen,
-                                     tag, 16 ) );
+    TEST_ASSERT( 0 == cipher_finish( &ctx_dec, decbuf + outlen, &outlen ) );
     total_len += outlen;
 
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+    TEST_ASSERT( 0 == cipher_check_tag( &ctx_dec, tag, 16 ) );
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
+
     TEST_ASSERT( total_len == length );
 
     TEST_ASSERT( 0 == memcmp(inbuf, decbuf, length) );
@@ -133,11 +151,15 @@
     TEST_ASSERT( 0 == cipher_init_ctx( &ctx, cipher_info ) );
     TEST_ASSERT( 0 == cipher_setkey( &ctx, key, key_len, POLARSSL_ENCRYPT ) );
     TEST_ASSERT( 0 == cipher_set_padding_mode( &ctx, pad_mode ) );
-    TEST_ASSERT( 0 == cipher_reset( &ctx, iv, 16, NULL, 0 ) );
+    TEST_ASSERT( 0 == cipher_set_iv( &ctx, iv, 16 ) );
+    TEST_ASSERT( 0 == cipher_reset( &ctx ) );
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+    TEST_ASSERT( 0 == cipher_update_ad( &ctx, NULL, 0 ) );
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
 
     /* encode length number of bytes from inbuf */
     TEST_ASSERT( 0 == cipher_update( &ctx, inbuf, length, encbuf, &outlen ) );
-    TEST_ASSERT( ret == cipher_finish( &ctx, encbuf + outlen, &outlen, NULL, 0 ) );
+    TEST_ASSERT( ret == cipher_finish( &ctx, encbuf + outlen, &outlen ) );
 
     /* done */
     TEST_ASSERT( 0 == cipher_free_ctx( &ctx ) );
@@ -166,7 +188,7 @@
     memset( encbuf, 0, 64 );
     memset( decbuf, 0, 64 );
 
-    /* Initialise enc and dec contexts */
+    /* Initialise context */
     cipher_info = cipher_info_from_type( POLARSSL_CIPHER_AES_128_CBC );
     TEST_ASSERT( NULL != cipher_info);
     
@@ -174,13 +196,19 @@
 
     TEST_ASSERT( 0 == cipher_setkey( &ctx_dec, key, 128, POLARSSL_DECRYPT ) );
 
-    TEST_ASSERT( 0 == cipher_reset( &ctx_dec, iv, 16, NULL, 0 ) );
+    TEST_ASSERT( 0 == cipher_set_iv( &ctx_dec, iv, 16 ) );
+
+    TEST_ASSERT( 0 == cipher_reset( &ctx_dec ) );
+
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+    TEST_ASSERT( 0 == cipher_update_ad( &ctx_dec, NULL, 0 ) );
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
 
     /* decode 0-byte string */
     TEST_ASSERT( 0 == cipher_update( &ctx_dec, encbuf, 0, decbuf, &outlen ) );
     TEST_ASSERT( 0 == outlen );
     TEST_ASSERT( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED == cipher_finish(
-                 &ctx_dec, decbuf + outlen, &outlen, NULL, 0 ) );
+                 &ctx_dec, decbuf + outlen, &outlen ) );
     TEST_ASSERT( 0 == outlen );
 
     TEST_ASSERT( 0 == cipher_free_ctx( &ctx_dec ) );
@@ -228,8 +256,16 @@
     TEST_ASSERT( 0 == cipher_setkey( &ctx_dec, key, key_len, POLARSSL_DECRYPT ) );
     TEST_ASSERT( 0 == cipher_setkey( &ctx_enc, key, key_len, POLARSSL_ENCRYPT ) );
 
-    TEST_ASSERT( 0 == cipher_reset( &ctx_dec, iv, 16, NULL, 0 ) );
-    TEST_ASSERT( 0 == cipher_reset( &ctx_enc, iv, 16, NULL, 0 ) );
+    TEST_ASSERT( 0 == cipher_set_iv( &ctx_dec, iv, 16 ) );
+    TEST_ASSERT( 0 == cipher_set_iv( &ctx_enc, iv, 16 ) );
+
+    TEST_ASSERT( 0 == cipher_reset( &ctx_dec ) );
+    TEST_ASSERT( 0 == cipher_reset( &ctx_enc ) );
+
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+    TEST_ASSERT( 0 == cipher_update_ad( &ctx_dec, NULL, 0 ) );
+    TEST_ASSERT( 0 == cipher_update_ad( &ctx_enc, NULL, 0 ) );
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
 
     /* encode length number of bytes from inbuf */
     TEST_ASSERT( 0 == cipher_update( &ctx_enc, inbuf, first_length, encbuf, &outlen ) );
@@ -241,8 +277,7 @@
                    totaloutlen < length &&
                    totaloutlen + cipher_get_block_size( &ctx_enc ) > length ) );
 
-    TEST_ASSERT( 0 == cipher_finish( &ctx_enc, encbuf + totaloutlen, &outlen,
-                                     NULL, 0 ) );
+    TEST_ASSERT( 0 == cipher_finish( &ctx_enc, encbuf + totaloutlen, &outlen ) );
     totaloutlen += outlen;
     TEST_ASSERT( totaloutlen == length ||
                  ( totaloutlen % cipher_get_block_size( &ctx_enc ) == 0 &&
@@ -258,8 +293,7 @@
                    totaloutlen < length &&
                    totaloutlen + cipher_get_block_size( &ctx_dec ) >= length ) );
 
-    TEST_ASSERT( 0 == cipher_finish( &ctx_dec, decbuf + outlen, &outlen,
-                                     NULL, 0 ) );
+    TEST_ASSERT( 0 == cipher_finish( &ctx_dec, decbuf + outlen, &outlen ) );
     totaloutlen += outlen;
 
     TEST_ASSERT( totaloutlen == length );
@@ -272,6 +306,73 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void decrypt_test_vec( int cipher_id, int pad_mode,
+                       char *hex_key, char *hex_iv,
+                       char *hex_cipher, char *hex_clear,
+                       char *hex_ad, char *hex_tag,
+                       int finish_result, int tag_result )
+{
+    unsigned char key[50];
+    unsigned char iv[50];
+    unsigned char cipher[200];
+    unsigned char clear[200];
+    unsigned char ad[200];
+    unsigned char tag[20];
+    size_t key_len, iv_len, cipher_len, clear_len, ad_len, tag_len;
+    cipher_context_t ctx;
+    unsigned char output[200];
+    size_t outlen, total_len;
+
+    memset( key, 0x00, sizeof( key ) );
+    memset( iv, 0x00, sizeof( iv ) );
+    memset( cipher, 0x00, sizeof( cipher ) );
+    memset( clear, 0x00, sizeof( clear ) );
+    memset( ad, 0x00, sizeof( ad ) );
+    memset( tag, 0x00, sizeof( tag ) );
+    memset( output, 0x00, sizeof( output ) );
+
+    key_len = unhexify( key, hex_key );
+    iv_len = unhexify( iv, hex_iv );
+    cipher_len = unhexify( cipher, hex_cipher );
+    clear_len = unhexify( clear, hex_clear );
+    ad_len = unhexify( ad, hex_ad );
+    tag_len = unhexify( tag, hex_tag );
+
+    /* Prepare context */
+    TEST_ASSERT( 0 == cipher_init_ctx( &ctx,
+                                       cipher_info_from_type( cipher_id ) ) );
+    TEST_ASSERT( 0 == cipher_setkey( &ctx, key, 8 * key_len, POLARSSL_DECRYPT ) );
+    if( pad_mode != -1 )
+        TEST_ASSERT( 0 == cipher_set_padding_mode( &ctx, pad_mode ) );
+    TEST_ASSERT( 0 == cipher_set_iv( &ctx, iv, iv_len ) );
+    TEST_ASSERT( 0 == cipher_reset( &ctx ) );
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+    TEST_ASSERT( 0 == cipher_update_ad( &ctx, ad, ad_len ) );
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
+
+    /* decode buffer and check tag */
+    total_len = 0;
+    TEST_ASSERT( 0 == cipher_update( &ctx, cipher, cipher_len, output, &outlen ) );
+    total_len += outlen;
+    TEST_ASSERT( finish_result == cipher_finish( &ctx, output + outlen,
+                                                 &outlen ) );
+    total_len += outlen;
+#if defined(POLARSSL_CIPHER_MODE_AEAD)
+    TEST_ASSERT( tag_result == cipher_check_tag( &ctx, tag, tag_len ) );
+#endif /* POLARSSL_CIPHER_MODE_AEAD */
+
+    /* check plaintext only if everything went fine */
+    if( 0 == finish_result && 0 == tag_result )
+    {
+        TEST_ASSERT( total_len == clear_len );
+        TEST_ASSERT( 0 == memcmp( output, clear, clear_len ) );
+    }
+
+    cipher_free_ctx( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void set_padding( int cipher_id, int pad_mode, int ret )
 {
     const cipher_info_t *cipher_info;
diff --git a/tests/suites/test_suite_cipher.gcm.data b/tests/suites/test_suite_cipher.gcm.data
index aacdca8..7a83dc5 100644
--- a/tests/suites/test_suite_cipher.gcm.data
+++ b/tests/suites/test_suite_cipher.gcm.data
@@ -108,3 +108,39 @@
 AES 128 GCM Encrypt and decrypt 32 bytes in multiple parts 1
 depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
 enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:16:16
+
+AES 128 GCM Decrypt test vector #1
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_GCM:-1:"d785dafea3e966731ef6fc6202262584":"d91a46205ee94058b3b8403997592dd2":"":"":"":"3b92a17c1b9c3578a68cffea5a5b6245":0:0
+
+AES 128 GCM Decrypt test vector #2
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_GCM:-1:"9ab5c8ca905b5fe50461f4a68941144b":"96dd3927a96e16123f2e9d6b367d303f":"":"":"":"6e0c53ef":0:0
+
+AES 128 GCM Decrypt test vector #3
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_GCM:-1:"b5fc7af605721a9cfe61c1ee6a4b3e22":"6b757d4055823d1035d01077666037d6":"":"":"":"e8c09ddd":0:POLARSSL_ERR_GCM_AUTH_FAILED
+
+AES 128 GCM Decrypt test vector #4
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_GCM:-1:"03c0b4a6e508a8490db0d086a82c9db7":"ac52f6c1a05030321fa39f87e89fdb5e":"":"":"33316ca79d10a79f4fd038593e8eef09625089dc4e0ffe4bc1f2871554fa6666ab3e7fe7885edef694b410456f3ec0e513bb25f1b48d95e4820c5972c1aabb25c84c08566002dadc36df334c1ce86847964a122016d389ac873bca8c335a7a99bcef91e1b985ae5d488a2d7f78b4bf14e0c2dc715e814f4e24276057cf668172":"756292d8b4653887edef51679b161812":0:POLARSSL_ERR_GCM_AUTH_FAILED
+
+AES 128 GCM Decrypt test vector #5
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_GCM:-1:"2bc73fba942ff105823b5dccf6befb1c":"902c3e3b69b1ef8395d7281ff74cce38":"":"":"4adec0b4ac00325a860044d9f9519daa4f7c163229a75819b0fd7d8e23319f030e61dfa8eadabff42ea27bc36bdb6cad249e801ca631b656836448b7172c11126bad2781e6a1aa4f62c4eda53409408b008c057e0b81215cc13ddabbb8f1915f4bbab854f8b00763a530ad5055d265778cd3080d0bd35b76a329bdd5b5a2d268":"ebdd7c8e87fe733138a433543542d1":0:0
+
+AES 128 GCM Decrypt test vector #6
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_GCM:-1:"0dd358bc3f992f26e81e3a2f3aa2d517":"d8c750bb443ee1a169dfe97cfe4d855b":"87cc4fd75788c9d5cc83bae5d764dd249d178ab23224049795d4288b5ed9ea3f317068a39a7574b300c8544226e87b08e008fbe241d094545c211d56ac44437d41491a438272738968c8d371aa7787b5f606c8549a9d868d8a71380e9657d3c0337979feb01de5991fc1470dfc59eb02511efbbff3fcb479a862ba3844a25aaa":"77949b29f085bb3abb71a5386003811233056d3296eb093370f7777dadd306d93d59dcb9754d3857cf2758091ba661f845ef0582f6ae0e134328106f0d5d16b541cd74fdc756dc7b53f4f8a194daeea9369ebb1630c01ccb307b848e9527da20a39898d748fd59206f0b79d0ed946a8958033a45bd9ae673518b32606748eb65":"":"a81d13973baa22a751833d7d3f94b3b1":0:0
+
+AES 128 GCM Decrypt test vector #7
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_GCM:-1:"9a433c612d7e1bdff881e4d63ba8b141":"8b670cf31f470f79a6c0b79e73863ca1":"ce10758332f423228b5e4ae31efda7677586934a1d8f05d9b7a0dc4e2010ec3eaacb71a527a5fff8e787d75ebd24ad163394c891b33477ed9e2a2d853c364cb1c5d0bc317fcaf4010817dbe5f1fd1037c701b291b3a66b164bc818bf5c00a4c210a1671faa574d74c7f3543f6c09aaf117e12e2eb3dae55edb1cc5b4086b617d":"":"":"8526fd25daf890e79946a205b698f287":0:POLARSSL_ERR_GCM_AUTH_FAILED
+
+AES 128 GCM Decrypt test vector #8
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_GCM:-1:"69eedf3777e594c30e94e9c5e2bce467":"a3330638a809ba358d6c098e4342b81e":"5114e9983c96fecec3f7304ca42f52aa16cb7c6aadfb62ad537c93a3188835ca0703dad34c73cf96435b668b68a7a1d056931959316e8d3ab956bf64c4e07479c7767f9d488b0c0c351333ccf400b7e0be19a0fd173e3f2a1ae313f27e516952260fd2da9ab9daca478ebb93cd07d0b7503b32364d8e308d904d966c58f226bb":"208e6321238bf5c6e2ef55a4b8f531cbbfb0d77374fe32df6dd663486cf79beeed39bb6910c3c78dd0cc30707a0a12b226b2d06024db25dcd8a4e620f009cafa5242121e864c7f3f4360aaf1e9d4e548d99615156f156008418c1c41ff2bbc007cecf8f209c73203e6df89b32871de637b3d6af2e277d146ae03f3404d387b77":"df4e3f2b47cf0e8590228fcf9913fb8a5eb9751bba318fd2d57be68c7e788e04fabf303699b99f26313d1c4956105cd2817aad21b91c28f3b9251e9c0b354490fa5abfcea0065aa3cc9b96772eb8af06a1a9054bf12d3ae698dfb01a13f989f8b8a4bb61686cf3adf58f05873a24d403a62a092290c2481e4159588fea6b9a09":"5de3068e1e20eed469265000077b1db9":0:0
+
+AES 128 GCM Decrypt test vector #9
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+decrypt_test_vec:POLARSSL_CIPHER_AES_128_GCM:-1:"45cc35311eedf0ba093bf901931a7036":"fed5084de3c348f5a0adf4c2fd4e848a":"5dc8d7525eaad035c19714ae1b1e538cb66a4089027245351e0ad9297410fb3a0c1155407c10a8bb95a9ca624a9c9925dac003ee78926c6e90ff4ccdba10e8a78bda1c4478162a0e302de5ff05fb0f94c89c3c7429fb94828bdcd97d21333c2ee72963ee6f056ce272b8bab007e653a42b01d1d2041ba627f169c8c0d32e6dae":"":"6e210914e4aed188d576f5ad7fc7e4cf7dd8d82f34ea3bcbdb7267cfd9045f806978dbff3460c4e8ff8c4edb6ad2edba405a8d915729d89aab2116b36a70b54f5920a97f5a571977e0329eda6c696749be940eabfc6d8b0bbd6fbdb87657b3a7695da9f5d3a7384257f20e0becd8512d3705cc246ee6ca1e610921cf92603d79":"266a895fc21da5176b44b446d7d1921d":0:POLARSSL_ERR_GCM_AUTH_FAILED
diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function
index c00ec0b..2b870d1 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -95,6 +95,7 @@
         }
         else
         {
+            TEST_ASSERT( ret == 0 );
             hexify( dst_str, output, pt_len );
 
             TEST_ASSERT( strcmp( (char *) dst_str, pt_result ) == 0 );