Merged current cipher enhancements for ARC4 and AES-GCM
diff --git a/include/polarssl/cipher.h b/include/polarssl/cipher.h
index 0ab2b56..ef037be 100644
--- a/include/polarssl/cipher.h
+++ b/include/polarssl/cipher.h
@@ -95,7 +95,6 @@
 
 typedef enum {
     POLARSSL_MODE_NONE = 0,
-    POLARSSL_MODE_NULL,
     POLARSSL_MODE_CBC,
     POLARSSL_MODE_CFB,
     POLARSSL_MODE_OFB,
@@ -151,6 +150,10 @@
     int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, unsigned char *nonce_counter,
             unsigned char *stream_block, const unsigned char *input, unsigned char *output );
 
+    /** Encrypt using STREAM */
+    int (*stream_func)( void *ctx, size_t length,
+                        const unsigned char *input, unsigned char *output );
+
     /** Set key for encryption purposes */
     int (*setkey_enc_func)( void *ctx, const unsigned char *key, unsigned int key_length);
 
@@ -317,7 +320,7 @@
  * \param ctx           cipher's context. Must have been initialised.
  *
  * \return              size of the cipher's IV, or 0 if ctx has not been
- *                      initialised.
+ *                      initialised or accepts IV of various sizes.
  */
 static inline int cipher_get_iv_size( const cipher_context_t *ctx )
 {
@@ -429,11 +432,18 @@
  *
  * \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 );
+int cipher_reset( cipher_context_t *ctx,
+                  const unsigned char *iv, size_t iv_len,
+                  const unsigned char *ad, size_t ad_len );
 
 /**
  * \brief               Generic cipher update function. Encrypts/decrypts
@@ -468,8 +478,13 @@
  *                      the last block, and written to the output buffer.
  *
  * \param ctx           Generic cipher context
- * \param output        buffer to write data to. Needs block_size data available.
+ * \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,
@@ -478,7 +493,9 @@
  *                      POLARSSL_ERR_CIPHER_INVALID_PADDING on invalid padding
  *                      while decrypting or a cipher specific error code.
  */
-int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen);
+int cipher_finish( cipher_context_t *ctx,
+                   unsigned char *output, size_t *olen,
+                   unsigned char *tag, size_t tag_len );
 
 /**
  * \brief          Checkup routine
diff --git a/include/polarssl/gcm.h b/include/polarssl/gcm.h
index 2bed342..dc058dc 100644
--- a/include/polarssl/gcm.h
+++ b/include/polarssl/gcm.h
@@ -146,7 +146,7 @@
  * \param mode      GCM_ENCRYPT or GCM_DECRYPT
  * \param iv        initialization vector
  * \param iv_len    length of IV
- * \param add       additional data
+ * \param add       additional data (or NULL if length is 0)
  * \param add_len   length of additional data
  *
  * \return         0 if successful
@@ -182,14 +182,14 @@
 
 /**
  * \brief           Generic GCM finalisation function. Wraps up the GCM stream
- *                  and generated the tag. The tag can have a maximum length of
+ *                  and generates the tag. The tag can have a maximum length of
  *                  16 bytes.
  *
  * \param ctx       GCM context
- * \param tag       buffer for holding the tag
+ * \param tag       buffer for holding the tag (may be NULL if tag_len is 0)
  * \param tag_len   length of the tag to generate
  *
- * \return         0 if successful or POLARSSL_ERR_GCM_BAD_INPUT
+ * \return          0 if successful or POLARSSL_ERR_GCM_BAD_INPUT
  */
 int gcm_finish( gcm_context *ctx,
                 unsigned char *tag,
diff --git a/library/cipher.c b/library/cipher.c
index 826d8fc..d7cac05 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -34,8 +34,16 @@
 #include "polarssl/cipher.h"
 #include "polarssl/cipher_wrap.h"
 
+#if defined(POLARSSL_GCM_C)
+#include "polarssl/gcm.h"
+#endif
+
 #include <stdlib.h>
 
+#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER)
+#define POLARSSL_CIPHER_MODE_STREAM
+#endif
+
 #if defined _MSC_VER && !defined strcasecmp
 #define strcasecmp _stricmp
 #endif
@@ -61,6 +69,10 @@
 
 #endif /* defined(POLARSSL_AES_C) */
 
+#if defined(POLARSSL_ARC4_C)
+        POLARSSL_CIPHER_ARC4_128,
+#endif
+
 #if defined(POLARSSL_CAMELLIA_C)
         POLARSSL_CIPHER_CAMELLIA_128_CBC,
         POLARSSL_CIPHER_CAMELLIA_192_CBC,
@@ -277,6 +289,18 @@
     if( !strcasecmp( "AES-256-CTR", cipher_name ) )
         return cipher_info_from_type( POLARSSL_CIPHER_AES_256_CTR );
 #endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
+
+#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-256-GCM", cipher_name ) )
+        return cipher_info_from_type( POLARSSL_CIPHER_AES_256_GCM );
+#endif
+#endif /* POLARSSL_AES_C */
+
+#if defined(POLARSSL_ARC4_C)
+    if( !strcasecmp( "ARC4-128", cipher_name ) )
+        return( cipher_info_from_type( POLARSSL_CIPHER_ARC4_128 ) );
 #endif
 
 #if defined(POLARSSL_DES_C)
@@ -354,11 +378,6 @@
     ctx->key_length = key_length;
     ctx->operation = operation;
 
-#if defined(POLARSSL_CIPHER_NULL_CIPHER)
-    if( ctx->cipher_info->mode == POLARSSL_MODE_NULL )
-        return 0;
-#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
-
     /*
      * For CFB and CTR mode always use the encryption key schedule
      */
@@ -377,13 +396,27 @@
     return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
 }
 
-int cipher_reset( cipher_context_t *ctx, const unsigned char *iv )
+int cipher_reset( cipher_context_t *ctx,
+                  const unsigned char *iv, size_t iv_len,
+                  const unsigned char *ad, size_t ad_len )
 {
     if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
         return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
 
     ctx->unprocessed_len = 0;
 
+#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
+
     memcpy( ctx->iv, iv, cipher_get_iv_size( ctx ) );
 
     return 0;
@@ -408,20 +441,8 @@
         return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
     }
 
-#if defined(POLARSSL_CIPHER_NULL_CIPHER)
-    if( ctx->cipher_info->mode == POLARSSL_MODE_NULL )
-    {
-        *olen = ilen;
-
-        if( output == input )
-            return( 0 );
-
-        memcpy( output, input, ilen );
-        return 0;
-    }
-#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
-
-    if( ctx->cipher_info->mode == POLARSSL_MODE_CBC )
+    if( ctx->cipher_info->mode == POLARSSL_MODE_CBC ||
+        ctx->cipher_info->mode == POLARSSL_MODE_GCM )
     {
         /*
          * If there is not enough data for a full block, cache it.
@@ -448,6 +469,18 @@
             memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
                     copy_len );
 
+#if defined(POLARSSL_GCM_C)
+            if( ctx->cipher_info->mode == POLARSSL_MODE_GCM )
+            {
+                if( 0 != ( ret = gcm_update( ctx->cipher_ctx,
+                                cipher_get_block_size( ctx ),
+                                ctx->unprocessed_data, output ) ) )
+                {
+                    return ret;
+                }
+            }
+            else
+#endif
             if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
                     ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
                     ctx->unprocessed_data, output ) ) )
@@ -484,11 +517,23 @@
          */
         if( ilen )
         {
+#if defined(POLARSSL_GCM_C)
+            if( ctx->cipher_info->mode == POLARSSL_MODE_GCM )
+            {
+                if( 0 != ( ret = gcm_update( ctx->cipher_ctx,
+                                             ilen, input, output ) ) )
+                {
+                    return ret;
+                }
+            }
+            else
+#endif
             if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
                     ctx->operation, ilen, ctx->iv, input, output ) ) )
             {
                 return ret;
             }
+
             *olen += ilen;
         }
 
@@ -527,6 +572,21 @@
     }
 #endif
 
+#if defined(POLARSSL_CIPHER_MODE_STREAM)
+    if( ctx->cipher_info->mode == POLARSSL_MODE_STREAM )
+    {
+        if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
+                                                    ilen, input, output ) ) )
+        {
+            return ret;
+        }
+
+        *olen = ilen;
+
+        return 0;
+    }
+#endif
+
     return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
 }
 
@@ -686,7 +746,9 @@
     return 0;
 }
 
-int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen)
+int cipher_finish( cipher_context_t *ctx,
+                   unsigned char *output, size_t *olen,
+                   unsigned char *tag, size_t tag_len )
 {
     int ret = 0;
 
@@ -697,11 +759,52 @@
 
     if( POLARSSL_MODE_CFB == ctx->cipher_info->mode ||
         POLARSSL_MODE_CTR == ctx->cipher_info->mode ||
-        POLARSSL_MODE_NULL == ctx->cipher_info->mode )
+        POLARSSL_MODE_STREAM == ctx->cipher_info->mode )
     {
         return 0;
     }
 
+#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 ) ) )
+        {
+            return( ret );
+        }
+
+        *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 )
     {
         if( POLARSSL_ENCRYPT == ctx->operation )
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index baff2aa..5c98100 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -37,6 +37,10 @@
 #include "polarssl/aes.h"
 #endif
 
+#if defined(POLARSSL_ARC4_C)
+#include "polarssl/arc4.h"
+#endif
+
 #if defined(POLARSSL_CAMELLIA_C)
 #include "polarssl/camellia.h"
 #endif
@@ -49,6 +53,10 @@
 #include "polarssl/blowfish.h"
 #endif
 
+#if defined(POLARSSL_GCM_C)
+#include "polarssl/gcm.h"
+#endif
+
 #if defined(POLARSSL_MEMORY_C)
 #include "polarssl/memory.h"
 #else
@@ -129,6 +137,7 @@
     aes_crypt_cbc_wrap,
     aes_crypt_cfb128_wrap,
     aes_crypt_ctr_wrap,
+    NULL,
     aes_setkey_enc_wrap,
     aes_setkey_dec_wrap,
     aes_ctx_alloc,
@@ -230,14 +239,41 @@
 #endif /* POLARSSL_CIPHER_MODE_CTR */
 
 #if defined(POLARSSL_GCM_C)
+static void *gcm_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( gcm_context ) );
+}
+
+static void gcm_ctx_free( void *ctx )
+{
+    polarssl_free( ctx );
+}
+
+static int gcm_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+{
+    return gcm_init( (gcm_context *) ctx, key, key_length );
+}
+
+const cipher_base_t gcm_aes_info = {
+    POLARSSL_CIPHER_ID_AES,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    gcm_setkey_wrap,
+    gcm_setkey_wrap,
+    gcm_ctx_alloc,
+    gcm_ctx_free,
+};
+
 const cipher_info_t aes_128_gcm_info = {
     POLARSSL_CIPHER_AES_128_GCM,
     POLARSSL_MODE_GCM,
     128,
     "AES-128-GCM",
+    0,
     16,
-    16,
-    &aes_info
+    &gcm_aes_info
 };
 
 const cipher_info_t aes_256_gcm_info = {
@@ -245,9 +281,9 @@
     POLARSSL_MODE_GCM,
     256,
     "AES-256-GCM",
+    0,
     16,
-    16,
-    &aes_info
+    &gcm_aes_info
 };
 #endif /* POLARSSL_GCM_C */
 
@@ -324,6 +360,7 @@
     camellia_crypt_cbc_wrap,
     camellia_crypt_cfb128_wrap,
     camellia_crypt_ctr_wrap,
+    NULL,
     camellia_setkey_enc_wrap,
     camellia_setkey_dec_wrap,
     camellia_ctx_alloc,
@@ -531,6 +568,7 @@
     des_crypt_cbc_wrap,
     des_crypt_cfb128_wrap,
     des_crypt_ctr_wrap,
+    NULL,
     des_setkey_enc_wrap,
     des_setkey_dec_wrap,
     des_ctx_alloc,
@@ -552,6 +590,7 @@
     des3_crypt_cbc_wrap,
     des_crypt_cfb128_wrap,
     des_crypt_ctr_wrap,
+    NULL,
     des3_set2key_enc_wrap,
     des3_set2key_dec_wrap,
     des3_ctx_alloc,
@@ -573,6 +612,7 @@
     des3_crypt_cbc_wrap,
     des_crypt_cfb128_wrap,
     des_crypt_ctr_wrap,
+    NULL,
     des3_set3key_enc_wrap,
     des3_set3key_dec_wrap,
     des3_ctx_alloc,
@@ -636,12 +676,7 @@
 #endif
 }
 
-static int blowfish_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
-{
-    return blowfish_setkey( (blowfish_context *) ctx, key, key_length );
-}
-
-static int blowfish_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
 {
     return blowfish_setkey( (blowfish_context *) ctx, key, key_length );
 }
@@ -661,8 +696,9 @@
     blowfish_crypt_cbc_wrap,
     blowfish_crypt_cfb64_wrap,
     blowfish_crypt_ctr_wrap,
-    blowfish_setkey_enc_wrap,
-    blowfish_setkey_dec_wrap,
+    NULL,
+    blowfish_setkey_wrap,
+    blowfish_setkey_wrap,
     blowfish_ctx_alloc,
     blowfish_ctx_free
 };
@@ -703,15 +739,28 @@
 #endif /* POLARSSL_BLOWFISH_C */
 
 #if defined(POLARSSL_ARC4_C)
-static void * arc4_ctx_alloc( void )
+static int arc4_crypt_stream_wrap( void *ctx, size_t length,
+                                   const unsigned char *input,
+                                   unsigned char *output )
 {
-    return (void *) 1;
+    return( arc4_crypt( (arc4_context *) ctx, length, input, output ) );
 }
 
+static int arc4_setkey_wrap( void *ctx, const unsigned char *key,
+                             unsigned int key_length )
+{
+    arc4_setup( (arc4_context *) ctx, key, key_length );
+    return( 0 );
+}
+
+static void * arc4_ctx_alloc( void )
+{
+    return polarssl_malloc( sizeof( arc4_context ) );
+}
 
 static void arc4_ctx_free( void *ctx )
 {
-    ((void) ctx);
+    polarssl_free( ctx );
 }
 
 const cipher_base_t arc4_base_info = {
@@ -719,8 +768,9 @@
     NULL,
     NULL,
     NULL,
-    NULL,
-    NULL,
+    arc4_crypt_stream_wrap,
+    arc4_setkey_wrap,
+    arc4_setkey_wrap,
     arc4_ctx_alloc,
     arc4_ctx_free
 };
@@ -737,12 +787,30 @@
 #endif /* POLARSSL_ARC4_C */
 
 #if defined(POLARSSL_CIPHER_NULL_CIPHER)
+static int null_crypt_stream( void *ctx, size_t length,
+                              const unsigned char *input,
+                              unsigned char *output )
+{
+    ((void) ctx);
+    memmove( output, input, length );
+    return( 0 );
+}
+
+static int null_setkey( void *ctx, const unsigned char *key,
+                        unsigned int key_length )
+{
+    ((void) ctx);
+    ((void) key);
+    ((void) key_length);
+
+    return( 0 );
+}
+
 static void * null_ctx_alloc( void )
 {
     return (void *) 1;
 }
 
-
 static void null_ctx_free( void *ctx )
 {
     ((void) ctx);
@@ -753,15 +821,16 @@
     NULL,
     NULL,
     NULL,
-    NULL,
-    NULL,
+    null_crypt_stream,
+    null_setkey,
+    null_setkey,
     null_ctx_alloc,
     null_ctx_free
 };
 
 const cipher_info_t null_cipher_info = {
     POLARSSL_CIPHER_NULL,
-    POLARSSL_MODE_NULL,
+    POLARSSL_MODE_STREAM,
     0,
     "NULL",
     0,
diff --git a/library/gcm.c b/library/gcm.c
index 3e9969d..99036a0 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -293,11 +293,12 @@
     uint64_t orig_len = ctx->len * 8;
     uint64_t orig_add_len = ctx->add_len * 8;
 
-    memcpy( tag, ctx->base_ectr, tag_len );
-
     if( tag_len > 16 )
         return( POLARSSL_ERR_GCM_BAD_INPUT );
 
+    if( tag_len != 0 )
+        memcpy( tag, ctx->base_ectr, tag_len );
+
     if( orig_len || orig_add_len )
     {
         memset( work_buf, 0x00, 16 );
@@ -357,15 +358,22 @@
                       unsigned char *output )
 {
     unsigned char check_tag[16];
+    size_t i;
+    int diff;
 
     gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
 
-    if( memcmp( check_tag, tag, tag_len ) == 0 )
-        return( 0 );
+    /* Check tag in "constant-time" */
+    for( diff = 0, i = 0; i < tag_len; i++ )
+        diff |= tag[i] ^ check_tag[i];
 
-    memset( output, 0, length );
+    if( diff != 0 )
+    {
+        memset( output, 0, length );
+        return( POLARSSL_ERR_GCM_AUTH_FAILED );
+    }
 
-    return( POLARSSL_ERR_GCM_AUTH_FAILED );
+    return( 0 );
 }
 
 #if defined(POLARSSL_SELF_TEST)
diff --git a/library/pkcs12.c b/library/pkcs12.c
index e0d7207..9ccb60a 100644
--- a/library/pkcs12.c
+++ b/library/pkcs12.c
@@ -184,7 +184,7 @@
     if( ( ret = cipher_setkey( &cipher_ctx, key, keylen, mode ) ) != 0 )
         goto exit;
 
-    if( ( ret = cipher_reset( &cipher_ctx, iv ) ) != 0 )
+    if( ( ret = cipher_reset( &cipher_ctx, iv, 0, NULL, 0 ) ) != 0 )
         goto exit;
 
     if( ( ret = cipher_update( &cipher_ctx, data, len,
@@ -193,8 +193,11 @@
         goto exit;
     }
 
-    if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
+    if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen, NULL, 0 ) )
+                != 0 )
+    {
         ret = POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH;
+    }
 
 exit:
     cipher_free_ctx( &cipher_ctx );
diff --git a/library/pkcs5.c b/library/pkcs5.c
index 9e3ce93..2b6a75a 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -187,7 +187,7 @@
     if( ( ret = cipher_setkey( &cipher_ctx, key, keylen, mode ) ) != 0 )
         goto exit;
 
-    if( ( ret = cipher_reset( &cipher_ctx, iv ) ) != 0 )
+    if( ( ret = cipher_reset( &cipher_ctx, iv, 0, NULL, 0 ) ) != 0 )
         goto exit;
 
     if( ( ret = cipher_update( &cipher_ctx, data, datalen,
@@ -196,8 +196,11 @@
         goto exit;
     }
 
-    if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
+    if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen, NULL, 0 ) )
+                != 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 47b17d5..a9b862e 100644
--- a/programs/aes/crypt_and_hash.c
+++ b/programs/aes/crypt_and_hash.c
@@ -306,7 +306,7 @@
             fprintf( stderr, "cipher_setkey() returned error\n");
             goto exit;
         }
-        if( cipher_reset( &cipher_ctx, IV ) != 0 )
+        if( cipher_reset( &cipher_ctx, IV, 16, NULL, 0 ) != 0 )
         {
             fprintf( stderr, "cipher_reset() returned error\n");
             goto exit;
@@ -338,7 +338,7 @@
             }
         }
 
-        if( cipher_finish( &cipher_ctx, output, &olen ) != 0 )
+        if( cipher_finish( &cipher_ctx, output, &olen, NULL, 0 ) != 0 )
         {
             fprintf( stderr, "cipher_finish() returned error\n" );
             goto exit;
@@ -424,7 +424,7 @@
 
         cipher_setkey( &cipher_ctx, digest, cipher_info->key_length,
             POLARSSL_DECRYPT );
-        cipher_reset( &cipher_ctx, IV);
+        cipher_reset( &cipher_ctx, IV, 16, NULL, 0 );
 
         md_hmac_starts( &md_ctx, digest, 32 );
 
@@ -455,7 +455,7 @@
         /*
          * Write the final block of data
          */
-        cipher_finish( &cipher_ctx, output, &olen );
+        cipher_finish( &cipher_ctx, output, &olen, NULL, 0 );
 
         if( fwrite( output, 1, olen, fout ) != olen )
         {
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 2bd41c0..20f3c8d 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -40,9 +40,11 @@
 add_test_suite(blowfish)
 add_test_suite(camellia)
 add_test_suite(cipher cipher.aes)
+add_test_suite(cipher cipher.arc4)
 add_test_suite(cipher cipher.blowfish)
 add_test_suite(cipher cipher.camellia)
 add_test_suite(cipher cipher.des)
+add_test_suite(cipher cipher.gcm)
 add_test_suite(cipher cipher.null)
 add_test_suite(cipher cipher.padding)
 add_test_suite(ctr_drbg)
diff --git a/tests/Makefile b/tests/Makefile
index 4d70858..4d2bcba 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -27,6 +27,7 @@
 		test_suite_arc4									\
 		test_suite_base64		test_suite_blowfish		\
 		test_suite_camellia		test_suite_cipher.aes	\
+		test_suite_cipher.arc4	test_suite_cipher.gcm	\
 		test_suite_cipher.blowfish						\
 		test_suite_cipher.camellia						\
 		test_suite_cipher.des	test_suite_cipher.null	\
@@ -74,6 +75,14 @@
 	echo   "  Generate	$@"
 	scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.aes
 
+test_suite_cipher.arc4.c : suites/test_suite_cipher.function suites/test_suite_cipher.arc4.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
+	echo   "  Generate	$@"
+	scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.arc4
+
+test_suite_cipher.gcm.c : suites/test_suite_cipher.function suites/test_suite_cipher.gcm.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
+	echo   "  Generate	$@"
+	scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.gcm
+
 test_suite_cipher.blowfish.c : suites/test_suite_cipher.function suites/test_suite_cipher.blowfish.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
 	echo   "  Generate	$@"
 	scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.blowfish
@@ -158,6 +167,14 @@
 	echo   "  CC    	$@.c"
 	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
 
+test_suite_cipher.arc4: test_suite_cipher.arc4.c ../library/libpolarssl.a
+	echo   "  CC    	$@.c"
+	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
+
+test_suite_cipher.gcm: test_suite_cipher.gcm.c ../library/libpolarssl.a
+	echo   "  CC    	$@.c"
+	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
+
 test_suite_cipher.blowfish: test_suite_cipher.blowfish.c ../library/libpolarssl.a
 	echo   "  CC    	$@.c"
 	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
diff --git a/tests/suites/test_suite_cipher.arc4.data b/tests/suites/test_suite_cipher.arc4.data
new file mode 100644
index 0000000..93d35b3
--- /dev/null
+++ b/tests/suites/test_suite_cipher.arc4.data
@@ -0,0 +1,110 @@
+Cipher Selftest
+depends_on:POLARSSL_SELF_TEST
+cipher_selftest:
+
+Decrypt empty buffer
+dec_empty_buf:
+
+ARC4 Encrypt and decrypt 0 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:0:-1
+
+ARC4 Encrypt and decrypt 1 byte
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:1:-1
+
+ARC4 Encrypt and decrypt 2 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:2:-1
+
+ARC4 Encrypt and decrypt 7 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:7:-1
+
+ARC4 Encrypt and decrypt 8 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:8:-1
+
+ARC4 Encrypt and decrypt 9 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:9:-1
+
+ARC4 Encrypt and decrypt 15 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:15:-1
+
+ARC4 Encrypt and decrypt 16 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:16:-1
+
+ARC4 Encrypt and decrypt 17 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:17:-1
+
+ARC4 Encrypt and decrypt 31 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:31:-1
+
+ARC4 Encrypt and decrypt 32 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:32:-1
+
+ARC4 Encrypt and decrypt 32 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:33:-1
+
+ARC4 Encrypt and decrypt 47 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:47:-1
+
+ARC4 Encrypt and decrypt 48 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:48:-1
+
+ARC4 Encrypt and decrypt 49 bytes
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf:POLARSSL_CIPHER_ARC4_128:"ARC4-128":128:49:-1
+
+ARC4 Encrypt and decrypt 0 bytes in multiple parts
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:0:0:
+
+ARC4 Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:1:0:
+
+ARC4 Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:0:1:
+
+ARC4 Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:16:0:
+
+ARC4 Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:0:16:
+
+ARC4 Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:1:15:
+
+ARC4 Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:15:1:
+
+ARC4 Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:15:7:
+
+ARC4 Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:16:6:
+
+ARC4 Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:17:6:
+
+ARC4 Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:POLARSSL_ARC4_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_ARC4_128:128:16:16:
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index 1f7943a4..b1814fa 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -14,6 +14,8 @@
     size_t length = length_val;
     unsigned char key[32];
     unsigned char iv[16];
+    unsigned char ad[13];
+    unsigned char tag[16];
 
     const cipher_info_t *cipher_info;
     cipher_context_t ctx_dec;
@@ -35,6 +37,8 @@
     memset( inbuf, 5, 64 );
     memset( encbuf, 0, 64 );
     memset( decbuf, 0, 64 );
+    memset( tag, 0, 16 );
+    memset( ad, 0x2a, 13 );
 
     /* Check and get info structures */
     cipher_info = cipher_info_from_type( cipher_id );
@@ -54,8 +58,8 @@
         TEST_ASSERT( 0 == cipher_set_padding_mode( &ctx_enc, pad_mode ) );
     }
 
-    TEST_ASSERT( 0 == cipher_reset( &ctx_dec, iv ) );
-    TEST_ASSERT( 0 == cipher_reset( &ctx_enc, iv ) );
+    TEST_ASSERT( 0 == cipher_reset( &ctx_dec, iv, 16, ad, 13 ) );
+    TEST_ASSERT( 0 == cipher_reset( &ctx_enc, iv, 16, ad, 13 ) );
 
     /* encode length number of bytes from inbuf */
     TEST_ASSERT( 0 == cipher_update( &ctx_enc, inbuf, length, encbuf, &outlen ) );
@@ -66,7 +70,8 @@
                    total_len < length &&
                    total_len + cipher_get_block_size( &ctx_enc ) > length ) );
 
-    TEST_ASSERT( 0 == cipher_finish( &ctx_enc, encbuf + outlen, &outlen ) );
+    TEST_ASSERT( 0 == cipher_finish( &ctx_enc, encbuf + outlen, &outlen,
+                                     tag, 16 ) );
     total_len += outlen;
 
     TEST_ASSERT( total_len == length ||
@@ -83,7 +88,8 @@
                    total_len < length &&
                    total_len + cipher_get_block_size( &ctx_dec ) >= length ) );
 
-    TEST_ASSERT( 0 == cipher_finish( &ctx_dec, decbuf + outlen, &outlen ) );
+    TEST_ASSERT( 0 == cipher_finish( &ctx_dec, decbuf + outlen, &outlen,
+                                     tag, 16 ) );
     total_len += outlen;
 
     TEST_ASSERT( total_len == length );
@@ -127,11 +133,11 @@
     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 ) );
+    TEST_ASSERT( 0 == cipher_reset( &ctx, iv, 16, NULL, 0 ) );
 
     /* 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 ) );
+    TEST_ASSERT( ret == cipher_finish( &ctx, encbuf + outlen, &outlen, NULL, 0 ) );
 
     /* done */
     TEST_ASSERT( 0 == cipher_free_ctx( &ctx ) );
@@ -168,12 +174,13 @@
 
     TEST_ASSERT( 0 == cipher_setkey( &ctx_dec, key, 128, POLARSSL_DECRYPT ) );
 
-    TEST_ASSERT( 0 == cipher_reset( &ctx_dec, iv ) );
+    TEST_ASSERT( 0 == cipher_reset( &ctx_dec, iv, 16, NULL, 0 ) );
 
     /* 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 ) );
+    TEST_ASSERT( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED == cipher_finish(
+                 &ctx_dec, decbuf + outlen, &outlen, NULL, 0 ) );
     TEST_ASSERT( 0 == outlen );
 
     TEST_ASSERT( 0 == cipher_free_ctx( &ctx_dec ) );
@@ -221,8 +228,8 @@
     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 ) );
-    TEST_ASSERT( 0 == cipher_reset( &ctx_enc, iv ) );
+    TEST_ASSERT( 0 == cipher_reset( &ctx_dec, iv, 16, NULL, 0 ) );
+    TEST_ASSERT( 0 == cipher_reset( &ctx_enc, iv, 16, NULL, 0 ) );
 
     /* encode length number of bytes from inbuf */
     TEST_ASSERT( 0 == cipher_update( &ctx_enc, inbuf, first_length, encbuf, &outlen ) );
@@ -234,7 +241,8 @@
                    totaloutlen < length &&
                    totaloutlen + cipher_get_block_size( &ctx_enc ) > length ) );
 
-    TEST_ASSERT( 0 == cipher_finish( &ctx_enc, encbuf + totaloutlen, &outlen ) );
+    TEST_ASSERT( 0 == cipher_finish( &ctx_enc, encbuf + totaloutlen, &outlen,
+                                     NULL, 0 ) );
     totaloutlen += outlen;
     TEST_ASSERT( totaloutlen == length ||
                  ( totaloutlen % cipher_get_block_size( &ctx_enc ) == 0 &&
@@ -248,9 +256,10 @@
     TEST_ASSERT( totaloutlen == length ||
                  ( totaloutlen % cipher_get_block_size( &ctx_dec ) == 0 &&
                    totaloutlen < length &&
-                   totaloutlen + cipher_get_block_size( &ctx_dec ) > length ) );
+                   totaloutlen + cipher_get_block_size( &ctx_dec ) >= length ) );
 
-    TEST_ASSERT( 0 == cipher_finish( &ctx_dec, decbuf + outlen, &outlen ) );
+    TEST_ASSERT( 0 == cipher_finish( &ctx_dec, decbuf + outlen, &outlen,
+                                     NULL, 0 ) );
     totaloutlen += outlen;
 
     TEST_ASSERT( totaloutlen == length );
diff --git a/tests/suites/test_suite_cipher.gcm.data b/tests/suites/test_suite_cipher.gcm.data
new file mode 100644
index 0000000..aacdca8
--- /dev/null
+++ b/tests/suites/test_suite_cipher.gcm.data
@@ -0,0 +1,110 @@
+Cipher Selftest
+depends_on:POLARSSL_SELF_TEST
+cipher_selftest:
+
+Decrypt empty buffer
+dec_empty_buf:
+
+AES-GCM Encrypt and decrypt 0 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:0:-1
+
+AES 128 GCM Encrypt and decrypt 1 byte
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:1:-1
+
+AES 128 GCM Encrypt and decrypt 2 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:2:-1
+
+AES 128 GCM Encrypt and decrypt 7 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:7:-1
+
+AES 128 GCM Encrypt and decrypt 8 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:8:-1
+
+AES 128 GCM Encrypt and decrypt 9 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:9:-1
+
+AES 128 GCM Encrypt and decrypt 15 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:15:-1
+
+AES 128 GCM Encrypt and decrypt 16 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:16:-1
+
+AES 128 GCM Encrypt and decrypt 17 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:17:-1
+
+AES 128 GCM Encrypt and decrypt 31 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:31:-1
+
+AES 128 GCM Encrypt and decrypt 32 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:32:-1
+
+AES 128 GCM Encrypt and decrypt 32 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:33:-1
+
+AES 128 GCM Encrypt and decrypt 47 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:47:-1
+
+AES 128 GCM Encrypt and decrypt 48 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:48:-1
+
+AES 128 GCM Encrypt and decrypt 49 bytes
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf:POLARSSL_CIPHER_AES_128_GCM:"AES-128-GCM":128:49:-1
+
+AES 128 GCM Encrypt and decrypt 0 bytes in multiple parts
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:0:0
+
+AES 128 GCM Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:1:0
+
+AES 128 GCM Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:0:1
+
+AES 128 GCM Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:16:0
+
+AES 128 GCM Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:0:16
+
+AES 128 GCM Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:1:15
+
+AES 128 GCM Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:15:1
+
+AES 128 GCM Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:15:7
+
+AES 128 GCM Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:16:6
+
+AES 128 GCM Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:POLARSSL_AES_C:POLARSSL_GCM_C
+enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:17:6
+
+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
diff --git a/tests/suites/test_suite_cipher.null.data b/tests/suites/test_suite_cipher.null.data
index 96aa36a..dd68277 100644
--- a/tests/suites/test_suite_cipher.null.data
+++ b/tests/suites/test_suite_cipher.null.data
@@ -7,59 +7,59 @@
 
 NULL Encrypt and decrypt 0 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:0
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:0:-1
 
 NULL Encrypt and decrypt 1 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:1
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:1:-1
 
 NULL Encrypt and decrypt 2 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:2
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:2:-1
 
 NULL Encrypt and decrypt 7 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:7
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:7:-1
 
 NULL Encrypt and decrypt 8 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:8
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:8:-1
 
 NULL Encrypt and decrypt 9 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:9
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:9:-1
 
 NULL Encrypt and decrypt 15 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:15
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:15:-1
 
 NULL Encrypt and decrypt 16 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:16
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:16:-1
 
 NULL Encrypt and decrypt 31 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:31
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:31:-1
 
 NULL Encrypt and decrypt 32 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:32
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:32:-1
 
 NULL Encrypt and decrypt 33 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:33
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:33:-1
 
 NULL Encrypt and decrypt 47 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:47
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:47:-1
 
 NULL Encrypt and decrypt 48 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:48
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:48:-1
 
 NULL Encrypt and decrypt 49 bytes
 depends_on:POLARSSL_CIPHER_NULL_CIPHER
-enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:49
+enc_dec_buf:POLARSSL_CIPHER_NULL:"NULL":0:49:-1
 
 NULL Encrypt and decrypt 1 bytes in multiple parts 1
 depends_on:POLARSSL_CIPHER_NULL_CIPHER