Merged GCM refactoring into development

GCM is now independent of AES and can be used as a mode for any
cipher-layer supported 128-bit based block cipher
diff --git a/include/polarssl/cipher.h b/include/polarssl/cipher.h
index aad488f..b7c03cb 100644
--- a/include/polarssl/cipher.h
+++ b/include/polarssl/cipher.h
@@ -70,6 +70,9 @@
 typedef enum {
     POLARSSL_CIPHER_NONE = 0,
     POLARSSL_CIPHER_NULL,
+    POLARSSL_CIPHER_AES_128_ECB,
+    POLARSSL_CIPHER_AES_192_ECB,
+    POLARSSL_CIPHER_AES_256_ECB,
     POLARSSL_CIPHER_AES_128_CBC,
     POLARSSL_CIPHER_AES_192_CBC,
     POLARSSL_CIPHER_AES_256_CBC,
@@ -82,6 +85,9 @@
     POLARSSL_CIPHER_AES_128_GCM,
     POLARSSL_CIPHER_AES_192_GCM,
     POLARSSL_CIPHER_AES_256_GCM,
+    POLARSSL_CIPHER_CAMELLIA_128_ECB,
+    POLARSSL_CIPHER_CAMELLIA_192_ECB,
+    POLARSSL_CIPHER_CAMELLIA_256_ECB,
     POLARSSL_CIPHER_CAMELLIA_128_CBC,
     POLARSSL_CIPHER_CAMELLIA_192_CBC,
     POLARSSL_CIPHER_CAMELLIA_256_CBC,
@@ -91,9 +97,13 @@
     POLARSSL_CIPHER_CAMELLIA_128_CTR,
     POLARSSL_CIPHER_CAMELLIA_192_CTR,
     POLARSSL_CIPHER_CAMELLIA_256_CTR,
+    POLARSSL_CIPHER_DES_ECB,
     POLARSSL_CIPHER_DES_CBC,
+    POLARSSL_CIPHER_DES_EDE_ECB,
     POLARSSL_CIPHER_DES_EDE_CBC,
+    POLARSSL_CIPHER_DES_EDE3_ECB,
     POLARSSL_CIPHER_DES_EDE3_CBC,
+    POLARSSL_CIPHER_BLOWFISH_ECB,
     POLARSSL_CIPHER_BLOWFISH_CBC,
     POLARSSL_CIPHER_BLOWFISH_CFB64,
     POLARSSL_CIPHER_BLOWFISH_CTR,
@@ -102,6 +112,7 @@
 
 typedef enum {
     POLARSSL_MODE_NONE = 0,
+    POLARSSL_MODE_ECB,
     POLARSSL_MODE_CBC,
     POLARSSL_MODE_CFB,
     POLARSSL_MODE_OFB,
@@ -145,6 +156,10 @@
     /** Base Cipher type (e.g. POLARSSL_CIPHER_ID_AES) */
     cipher_id_t cipher;
 
+    /** Encrypt using ECB */
+    int (*ecb_func)( void *ctx, operation_t mode,
+            const unsigned char *input, unsigned char *output );
+
     /** Encrypt using CBC */
     int (*cbc_func)( void *ctx, operation_t mode, size_t length, unsigned char *iv,
             const unsigned char *input, unsigned char *output );
@@ -271,6 +286,22 @@
 const cipher_info_t *cipher_info_from_type( const cipher_type_t cipher_type );
 
 /**
+ * \brief               Returns the cipher information structure associated
+ *                      with the given cipher id, key size and mode.
+ *
+ * \param cipher_id     Id of the cipher to search for
+ *                      (e.g. POLARSSL_CIPHER_ID_AES)
+ * \param key_length    Length of the key in bits
+ * \param mode          Cipher mode (e.g. POLARSSL_MODE_CBC)
+ *
+ * \return              the cipher information structure associated with the
+ *                      given cipher_type, or NULL if not found.
+ */
+const cipher_info_t *cipher_info_from_values( const cipher_id_t cipher_id,
+                                              int key_length,
+                                              const cipher_mode_t mode );
+
+/**
  * \brief               Initialises and fills the cipher context structure with
  *                      the appropriate values.
  *
@@ -497,6 +528,8 @@
  *                      that cannot be written immediately will either be added
  *                      to the next block, or flushed when cipher_final is
  *                      called.
+ *                      Exception: for POLARSSL_MODE_ECB, expects single block
+ *                                 in size (e.g. 16 bytes for AES)
  *
  * \param ctx           generic cipher context
  * \param input         buffer holding the input data
diff --git a/include/polarssl/cipher_wrap.h b/include/polarssl/cipher_wrap.h
index 8485256..9c26a10 100644
--- a/include/polarssl/cipher_wrap.h
+++ b/include/polarssl/cipher_wrap.h
@@ -38,6 +38,10 @@
 
 #if defined(POLARSSL_AES_C)
 
+extern const cipher_info_t aes_128_ecb_info;
+extern const cipher_info_t aes_192_ecb_info;
+extern const cipher_info_t aes_256_ecb_info;
+
 extern const cipher_info_t aes_128_cbc_info;
 extern const cipher_info_t aes_192_cbc_info;
 extern const cipher_info_t aes_256_cbc_info;
@@ -64,6 +68,10 @@
 
 #if defined(POLARSSL_CAMELLIA_C)
 
+extern const cipher_info_t camellia_128_ecb_info;
+extern const cipher_info_t camellia_192_ecb_info;
+extern const cipher_info_t camellia_256_ecb_info;
+
 extern const cipher_info_t camellia_128_cbc_info;
 extern const cipher_info_t camellia_192_cbc_info;
 extern const cipher_info_t camellia_256_cbc_info;
@@ -84,6 +92,10 @@
 
 #if defined(POLARSSL_DES_C)
 
+extern const cipher_info_t des_ecb_info;
+extern const cipher_info_t des_ede_ecb_info;
+extern const cipher_info_t des_ede3_ecb_info;
+
 extern const cipher_info_t des_cbc_info;
 extern const cipher_info_t des_ede_cbc_info;
 extern const cipher_info_t des_ede3_cbc_info;
@@ -91,6 +103,7 @@
 #endif /* defined(POLARSSL_DES_C) */
 
 #if defined(POLARSSL_BLOWFISH_C)
+extern const cipher_info_t blowfish_ecb_info;
 extern const cipher_info_t blowfish_cbc_info;
 
 #if defined(POLARSSL_CIPHER_MODE_CFB)
diff --git a/include/polarssl/gcm.h b/include/polarssl/gcm.h
index dc058dc..1997c4b 100644
--- a/include/polarssl/gcm.h
+++ b/include/polarssl/gcm.h
@@ -1,7 +1,7 @@
 /**
  * \file gcm.h
  *
- * \brief Galois/Counter mode for AES
+ * \brief Galois/Counter mode for 128-bit block ciphers
  *
  *  Copyright (C) 2006-2013, Brainspark B.V.
  *
@@ -27,7 +27,7 @@
 #ifndef POLARSSL_GCM_H
 #define POLARSSL_GCM_H
 
-#include "aes.h"
+#include "cipher.h"
 
 #ifdef _MSC_VER
 #include <basetsd.h>
@@ -50,7 +50,7 @@
  * \brief          GCM context structure
  */
 typedef struct {
-    aes_context aes_ctx;        /*!< AES context used */
+    cipher_context_t cipher_ctx;/*!< cipher context used */
     uint64_t HL[16];            /*!< Precalculated HTable */
     uint64_t HH[16];            /*!< Precalculated HTable */
     uint64_t len;               /*!< Total data length */
@@ -66,15 +66,17 @@
  * \brief           GCM initialization (encryption)
  *
  * \param ctx       GCM context to be initialized
+ * \param cipher    cipher to use (a 128-bit block cipher)
  * \param key       encryption key
  * \param keysize   must be 128, 192 or 256
  *
- * \return          0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
+ * \return          0 if successful, or a cipher specific error code
  */
-int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize );
+int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
+              unsigned int keysize );
 
 /**
- * \brief           GCM buffer encryption/decryption using AES
+ * \brief           GCM buffer encryption/decryption using a block cipher
  *
  * \note On encryption, the output buffer can be the same as the input buffer.
  *       On decryption, the output buffer cannot be the same as input buffer.
@@ -108,7 +110,7 @@
                        unsigned char *tag );
 
 /**
- * \brief           GCM buffer authenticated decryption using AES
+ * \brief           GCM buffer authenticated decryption using a block cipher
  *
  * \note On decryption, the output buffer cannot be the same as input buffer.
  *       If buffers overlap, the output buffer must trail at least 8 bytes
diff --git a/library/cipher.c b/library/cipher.c
index 8d90a64..8fded81 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -51,6 +51,9 @@
 static const int supported_ciphers[] = {
 
 #if defined(POLARSSL_AES_C)
+        POLARSSL_CIPHER_AES_128_ECB,
+        POLARSSL_CIPHER_AES_192_ECB,
+        POLARSSL_CIPHER_AES_256_ECB,
         POLARSSL_CIPHER_AES_128_CBC,
         POLARSSL_CIPHER_AES_192_CBC,
         POLARSSL_CIPHER_AES_256_CBC,
@@ -80,6 +83,9 @@
 #endif
 
 #if defined(POLARSSL_CAMELLIA_C)
+        POLARSSL_CIPHER_CAMELLIA_128_ECB,
+        POLARSSL_CIPHER_CAMELLIA_192_ECB,
+        POLARSSL_CIPHER_CAMELLIA_256_ECB,
         POLARSSL_CIPHER_CAMELLIA_128_CBC,
         POLARSSL_CIPHER_CAMELLIA_192_CBC,
         POLARSSL_CIPHER_CAMELLIA_256_CBC,
@@ -99,12 +105,16 @@
 #endif /* defined(POLARSSL_CAMELLIA_C) */
 
 #if defined(POLARSSL_DES_C)
+        POLARSSL_CIPHER_DES_ECB,
+        POLARSSL_CIPHER_DES_EDE_ECB,
+        POLARSSL_CIPHER_DES_EDE3_ECB,
         POLARSSL_CIPHER_DES_CBC,
         POLARSSL_CIPHER_DES_EDE_CBC,
         POLARSSL_CIPHER_DES_EDE3_CBC,
 #endif /* defined(POLARSSL_DES_C) */
 
 #if defined(POLARSSL_BLOWFISH_C)
+        POLARSSL_CIPHER_BLOWFISH_ECB,
         POLARSSL_CIPHER_BLOWFISH_CBC,
 
 #if defined(POLARSSL_CIPHER_MODE_CFB)
@@ -135,6 +145,13 @@
     switch ( cipher_type )
     {
 #if defined(POLARSSL_AES_C)
+        case POLARSSL_CIPHER_AES_128_ECB:
+            return &aes_128_ecb_info;
+        case POLARSSL_CIPHER_AES_192_ECB:
+            return &aes_192_ecb_info;
+        case POLARSSL_CIPHER_AES_256_ECB:
+            return &aes_256_ecb_info;
+
         case POLARSSL_CIPHER_AES_128_CBC:
             return &aes_128_cbc_info;
         case POLARSSL_CIPHER_AES_192_CBC:
@@ -172,6 +189,13 @@
 #endif
 
 #if defined(POLARSSL_CAMELLIA_C)
+        case POLARSSL_CIPHER_CAMELLIA_128_ECB:
+            return &camellia_128_ecb_info;
+        case POLARSSL_CIPHER_CAMELLIA_192_ECB:
+            return &camellia_192_ecb_info;
+        case POLARSSL_CIPHER_CAMELLIA_256_ECB:
+            return &camellia_256_ecb_info;
+
         case POLARSSL_CIPHER_CAMELLIA_128_CBC:
             return &camellia_128_cbc_info;
         case POLARSSL_CIPHER_CAMELLIA_192_CBC:
@@ -200,6 +224,13 @@
 #endif
 
 #if defined(POLARSSL_DES_C)
+        case POLARSSL_CIPHER_DES_ECB:
+            return &des_ecb_info;
+        case POLARSSL_CIPHER_DES_EDE_ECB:
+            return &des_ede_ecb_info;
+        case POLARSSL_CIPHER_DES_EDE3_ECB:
+            return &des_ede3_ecb_info;
+
         case POLARSSL_CIPHER_DES_CBC:
             return &des_cbc_info;
         case POLARSSL_CIPHER_DES_EDE_CBC:
@@ -214,6 +245,9 @@
 #endif
 
 #if defined(POLARSSL_BLOWFISH_C)
+        case POLARSSL_CIPHER_BLOWFISH_ECB:
+            return &blowfish_ecb_info;
+
         case POLARSSL_CIPHER_BLOWFISH_CBC:
             return &blowfish_cbc_info;
 
@@ -345,6 +379,185 @@
     return NULL;
 }
 
+const cipher_info_t *cipher_info_from_values( const cipher_id_t cipher_id,
+                                              int key_length,
+                                              const cipher_mode_t mode )
+{
+#if defined(POLARSSL_AES_C)
+    if( cipher_id == POLARSSL_CIPHER_ID_AES )
+    {
+        if( mode == POLARSSL_MODE_ECB )
+        {
+            if( key_length == 128 )
+                return &aes_128_ecb_info;
+            if( key_length == 192 )
+                return &aes_192_ecb_info;
+            if( key_length == 256 )
+                return &aes_256_ecb_info;
+        }
+
+        if( mode == POLARSSL_MODE_CBC )
+        {
+            if( key_length == 128 )
+                return &aes_128_cbc_info;
+            if( key_length == 192 )
+                return &aes_192_cbc_info;
+            if( key_length == 256 )
+                return &aes_256_cbc_info;
+        }
+
+#if defined(POLARSSL_CIPHER_MODE_CFB)
+        if( mode == POLARSSL_MODE_CFB )
+        {
+            if( key_length == 128 )
+                return &aes_128_cfb128_info;
+            if( key_length == 192 )
+                return &aes_192_cfb128_info;
+            if( key_length == 256 )
+                return &aes_256_cfb128_info;
+        }
+#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
+
+#if defined(POLARSSL_CIPHER_MODE_CTR)
+        if( mode == POLARSSL_MODE_CTR )
+        {
+            if( key_length == 128 )
+                return &aes_128_ctr_info;
+            if( key_length == 192 )
+                return &aes_192_ctr_info;
+            if( key_length == 256 )
+                return &aes_256_ctr_info;
+        }
+#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
+
+#if defined(POLARSSL_GCM_C)
+        if( mode == POLARSSL_MODE_GCM )
+        {
+            if( key_length == 128 )
+                return &aes_128_gcm_info;
+            if( key_length == 192 )
+                return &aes_192_gcm_info;
+            if( key_length == 256 )
+                return &aes_256_gcm_info;
+        }
+#endif /* defined(POLARSSL_GCM_C) */
+    }
+#endif
+
+#if defined(POLARSSL_CAMELLIA_C)
+    if( cipher_id == POLARSSL_CIPHER_ID_CAMELLIA )
+    {
+        if( mode == POLARSSL_MODE_ECB )
+        {
+            if( key_length == 128 )
+                return &camellia_128_ecb_info;
+            if( key_length == 192 )
+                return &camellia_192_ecb_info;
+            if( key_length == 256 )
+                return &camellia_256_ecb_info;
+        }
+
+        if( mode == POLARSSL_MODE_CBC )
+        {
+            if( key_length == 128 )
+                return &camellia_128_cbc_info;
+            if( key_length == 192 )
+                return &camellia_192_cbc_info;
+            if( key_length == 256 )
+                return &camellia_256_cbc_info;
+        }
+
+#if defined(POLARSSL_CIPHER_MODE_CFB)
+        if( mode == POLARSSL_MODE_CFB )
+        {
+            if( key_length == 128 )
+                return &camellia_128_cfb128_info;
+            if( key_length == 192 )
+                return &camellia_192_cfb128_info;
+            if( key_length == 256 )
+                return &camellia_256_cfb128_info;
+        }
+#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
+
+#if defined(POLARSSL_CIPHER_MODE_CTR)
+        if( mode == POLARSSL_MODE_CTR )
+        {
+            if( key_length == 128 )
+                return &camellia_128_ctr_info;
+            if( key_length == 192 )
+                return &camellia_192_ctr_info;
+            if( key_length == 256 )
+                return &camellia_256_ctr_info;
+        }
+#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
+    }
+#endif
+
+#if defined(POLARSSL_DES_C)
+    if( cipher_id == POLARSSL_CIPHER_ID_DES && key_length == 64 )
+    {
+        if( mode == POLARSSL_MODE_ECB )
+            return &des_ecb_info;
+
+        if( mode == POLARSSL_MODE_CBC )
+            return &des_cbc_info;
+    }
+
+    if( cipher_id == POLARSSL_CIPHER_ID_3DES )
+    {
+        if( mode == POLARSSL_MODE_ECB )
+        {
+            if( key_length == 128 )
+                return &des_ede_ecb_info;
+            if( key_length == 192 )
+                return &des_ede3_ecb_info;
+        }
+
+        if( mode == POLARSSL_MODE_CBC )
+        {
+            if( key_length == 128 )
+                return &des_ede_cbc_info;
+            if( key_length == 192 )
+                return &des_ede3_cbc_info;
+        }
+    }
+#endif
+
+#if defined(POLARSSL_ARC4_C)
+    if( cipher_id == POLARSSL_CIPHER_ID_ARC4 &&
+        key_length == 128 && mode == POLARSSL_MODE_STREAM )
+            return &arc4_128_info;
+#endif
+
+#if defined(POLARSSL_BLOWFISH_C)
+    if( cipher_id == POLARSSL_CIPHER_ID_BLOWFISH && key_length == 128 )
+    {
+        if( mode == POLARSSL_MODE_ECB )
+            return &blowfish_ecb_info;
+
+        if( mode == POLARSSL_MODE_CBC )
+            return &blowfish_cbc_info;
+
+#if defined(POLARSSL_CIPHER_MODE_CFB)
+        if( mode == POLARSSL_MODE_CFB )
+            return &blowfish_cfb64_info;
+#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
+
+#if defined(POLARSSL_CIPHER_MODE_CTR)
+        if( mode == POLARSSL_MODE_CTR )
+            return &blowfish_ctr_info;
+#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
+    }
+#endif
+
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+    if( cipher_id == POLARSSL_CIPHER_ID_NULL )
+            return &null_cipher_info;
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
+    return NULL;
+}
+
 int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info )
 {
     if( NULL == cipher_info || NULL == ctx )
@@ -467,8 +680,24 @@
         return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
     }
 
+    if( ctx->cipher_info->mode == POLARSSL_MODE_ECB )
+    {
+        if( ilen != cipher_get_block_size( ctx ) )
+            return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED;
+
+        *olen = ilen;
+
+        if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
+                    ctx->operation, input, output ) ) )
+        {
+            return ret;
+        }
+
+        return 0;
+    }
+
 #if defined(POLARSSL_GCM_C)
-    if( ctx->cipher_info->mode == POLARSSL_MODE_GCM)
+    if( ctx->cipher_info->mode == POLARSSL_MODE_GCM )
     {
         *olen = ilen;
         return gcm_update( ctx->cipher_ctx, ilen, input, output );
@@ -780,6 +1009,14 @@
         return 0;
     }
 
+    if( POLARSSL_MODE_ECB == ctx->cipher_info->mode )
+    {
+        if( ctx->unprocessed_len != 0 )
+            return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED;
+
+        return 0;
+    }
+
     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 f09823a..862328f 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -68,6 +68,12 @@
 
 #if defined(POLARSSL_AES_C)
 
+static int aes_crypt_ecb_wrap( void *ctx, operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    return aes_crypt_ecb( (aes_context *) ctx, operation, input, output );
+}
+
 static int aes_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
         unsigned char *iv, const unsigned char *input, unsigned char *output )
 {
@@ -134,6 +140,7 @@
 
 const cipher_base_t aes_info = {
     POLARSSL_CIPHER_ID_AES,
+    aes_crypt_ecb_wrap,
     aes_crypt_cbc_wrap,
     aes_crypt_cfb128_wrap,
     aes_crypt_ctr_wrap,
@@ -144,6 +151,39 @@
     aes_ctx_free
 };
 
+const cipher_info_t aes_128_ecb_info = {
+    POLARSSL_CIPHER_AES_128_ECB,
+    POLARSSL_MODE_ECB,
+    128,
+    "AES-128-ECB",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+const cipher_info_t aes_192_ecb_info = {
+    POLARSSL_CIPHER_AES_192_ECB,
+    POLARSSL_MODE_ECB,
+    192,
+    "AES-192-ECB",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+const cipher_info_t aes_256_ecb_info = {
+    POLARSSL_CIPHER_AES_256_ECB,
+    POLARSSL_MODE_ECB,
+    256,
+    "AES-256-ECB",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
 const cipher_info_t aes_128_cbc_info = {
     POLARSSL_CIPHER_AES_128_CBC,
     POLARSSL_MODE_CBC,
@@ -258,9 +298,10 @@
     polarssl_free( ctx );
 }
 
-static int gcm_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
+static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
 {
-    return gcm_init( (gcm_context *) ctx, key, key_length );
+    return gcm_init( (gcm_context *) ctx, POLARSSL_CIPHER_ID_AES,
+                     key, key_length );
 }
 
 const cipher_base_t gcm_aes_info = {
@@ -269,8 +310,9 @@
     NULL,
     NULL,
     NULL,
-    gcm_setkey_wrap,
-    gcm_setkey_wrap,
+    NULL,
+    gcm_aes_setkey_wrap,
+    gcm_aes_setkey_wrap,
     gcm_ctx_alloc,
     gcm_ctx_free,
 };
@@ -313,6 +355,12 @@
 
 #if defined(POLARSSL_CAMELLIA_C)
 
+static int camellia_crypt_ecb_wrap( void *ctx, operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    return camellia_crypt_ecb( (camellia_context *) ctx, operation, input, output );
+}
+
 static int camellia_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
         unsigned char *iv, const unsigned char *input, unsigned char *output )
 {
@@ -379,6 +427,7 @@
 
 const cipher_base_t camellia_info = {
     POLARSSL_CIPHER_ID_CAMELLIA,
+    camellia_crypt_ecb_wrap,
     camellia_crypt_cbc_wrap,
     camellia_crypt_cfb128_wrap,
     camellia_crypt_ctr_wrap,
@@ -389,6 +438,39 @@
     camellia_ctx_free
 };
 
+const cipher_info_t camellia_128_ecb_info = {
+    POLARSSL_CIPHER_CAMELLIA_128_ECB,
+    POLARSSL_MODE_ECB,
+    128,
+    "CAMELLIA-128-ECB",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+const cipher_info_t camellia_192_ecb_info = {
+    POLARSSL_CIPHER_CAMELLIA_192_ECB,
+    POLARSSL_MODE_ECB,
+    192,
+    "CAMELLIA-192-ECB",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+const cipher_info_t camellia_256_ecb_info = {
+    POLARSSL_CIPHER_CAMELLIA_256_ECB,
+    POLARSSL_MODE_ECB,
+    256,
+    "CAMELLIA-256-ECB",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
 const cipher_info_t camellia_128_cbc_info = {
     POLARSSL_CIPHER_CAMELLIA_128_CBC,
     POLARSSL_MODE_CBC,
@@ -496,6 +578,20 @@
 
 #if defined(POLARSSL_DES_C)
 
+static int des_crypt_ecb_wrap( void *ctx, operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    ((void) operation);
+    return des_crypt_ecb( (des_context *) ctx, input, output );
+}
+
+static int des3_crypt_ecb_wrap( void *ctx, operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    ((void) operation);
+    return des3_crypt_ecb( (des3_context *) ctx, input, output );
+}
+
 static int des_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
         unsigned char *iv, const unsigned char *input, unsigned char *output )
 {
@@ -596,6 +692,7 @@
 
 const cipher_base_t des_info = {
     POLARSSL_CIPHER_ID_DES,
+    des_crypt_ecb_wrap,
     des_crypt_cbc_wrap,
     des_crypt_cfb128_wrap,
     des_crypt_ctr_wrap,
@@ -606,6 +703,17 @@
     des_ctx_free
 };
 
+const cipher_info_t des_ecb_info = {
+    POLARSSL_CIPHER_DES_ECB,
+    POLARSSL_MODE_ECB,
+    POLARSSL_KEY_LENGTH_DES,
+    "DES-ECB",
+    8,
+    0,
+    8,
+    &des_info
+};
+
 const cipher_info_t des_cbc_info = {
     POLARSSL_CIPHER_DES_CBC,
     POLARSSL_MODE_CBC,
@@ -619,6 +727,7 @@
 
 const cipher_base_t des_ede_info = {
     POLARSSL_CIPHER_ID_DES,
+    des3_crypt_ecb_wrap,
     des3_crypt_cbc_wrap,
     des_crypt_cfb128_wrap,
     des_crypt_ctr_wrap,
@@ -629,6 +738,17 @@
     des_ctx_free
 };
 
+const cipher_info_t des_ede_ecb_info = {
+    POLARSSL_CIPHER_DES_EDE_ECB,
+    POLARSSL_MODE_ECB,
+    POLARSSL_KEY_LENGTH_DES_EDE,
+    "DES-EDE-ECB",
+    8,
+    0,
+    8,
+    &des_ede_info
+};
+
 const cipher_info_t des_ede_cbc_info = {
     POLARSSL_CIPHER_DES_EDE_CBC,
     POLARSSL_MODE_CBC,
@@ -642,6 +762,7 @@
 
 const cipher_base_t des_ede3_info = {
     POLARSSL_CIPHER_ID_DES,
+    des3_crypt_ecb_wrap,
     des3_crypt_cbc_wrap,
     des_crypt_cfb128_wrap,
     des_crypt_ctr_wrap,
@@ -652,6 +773,16 @@
     des_ctx_free
 };
 
+const cipher_info_t des_ede3_ecb_info = {
+    POLARSSL_CIPHER_DES_EDE3_ECB,
+    POLARSSL_MODE_ECB,
+    POLARSSL_KEY_LENGTH_DES_EDE3,
+    "DES-EDE3-ECB",
+    8,
+    0,
+    8,
+    &des_ede3_info
+};
 const cipher_info_t des_ede3_cbc_info = {
     POLARSSL_CIPHER_DES_EDE3_CBC,
     POLARSSL_MODE_CBC,
@@ -666,6 +797,12 @@
 
 #if defined(POLARSSL_BLOWFISH_C)
 
+static int blowfish_crypt_ecb_wrap( void *ctx, operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    return blowfish_crypt_ecb( (blowfish_context *) ctx, operation, input, output );
+}
+
 static int blowfish_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
         unsigned char *iv, const unsigned char *input, unsigned char *output )
 {
@@ -727,6 +864,7 @@
 
 const cipher_base_t blowfish_info = {
     POLARSSL_CIPHER_ID_BLOWFISH,
+    blowfish_crypt_ecb_wrap,
     blowfish_crypt_cbc_wrap,
     blowfish_crypt_cfb64_wrap,
     blowfish_crypt_ctr_wrap,
@@ -737,6 +875,17 @@
     blowfish_ctx_free
 };
 
+const cipher_info_t blowfish_ecb_info = {
+    POLARSSL_CIPHER_BLOWFISH_ECB,
+    POLARSSL_MODE_ECB,
+    128,
+    "BLOWFISH-ECB",
+    8,
+    0,
+    8,
+    &blowfish_info
+};
+
 const cipher_info_t blowfish_cbc_info = {
     POLARSSL_CIPHER_BLOWFISH_CBC,
     POLARSSL_MODE_CBC,
@@ -809,6 +958,7 @@
     NULL,
     NULL,
     NULL,
+    NULL,
     arc4_crypt_stream_wrap,
     arc4_setkey_wrap,
     arc4_setkey_wrap,
@@ -863,6 +1013,7 @@
     NULL,
     NULL,
     NULL,
+    NULL,
     null_crypt_stream,
     null_setkey,
     null_setkey,
diff --git a/library/gcm.c b/library/gcm.c
index 99036a0..1dfc199 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -54,15 +54,17 @@
 }
 #endif
 
-static void gcm_gen_table( gcm_context *ctx )
+static int gcm_gen_table( gcm_context *ctx )
 {
-    int i, j;
+    int ret, i, j;
     uint64_t hi, lo;
     uint64_t vl, vh;
     unsigned char h[16];
+    size_t olen = 0;
 
     memset( h, 0, 16 );
-    aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, h, h );
+    if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
+        return( ret );
 
     ctx->HH[0] = 0;
     ctx->HL[0] = 0;
@@ -99,18 +101,36 @@
             HiL[j] = vl ^ ctx->HL[j];
         }
     }
+
+    return( 0 );
 }
 
-int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize )
+int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key,
+              unsigned int keysize )
 {
     int ret;
+    const cipher_info_t *cipher_info;
 
     memset( ctx, 0, sizeof(gcm_context) );
 
-    if( ( ret = aes_setkey_enc( &ctx->aes_ctx, key, keysize ) ) != 0 )
+    cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB );
+    if( cipher_info == NULL )
+        return( POLARSSL_ERR_GCM_BAD_INPUT );
+
+    if( cipher_info->block_size != 16 )
+        return( POLARSSL_ERR_GCM_BAD_INPUT );
+
+    if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 )
         return( ret );
 
-    gcm_gen_table( ctx );
+    if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize,
+                               POLARSSL_ENCRYPT ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = gcm_gen_table( ctx ) ) != 0 )
+        return( ret );
 
     return( 0 );
 }
@@ -176,10 +196,11 @@
                 const unsigned char *add,
                 size_t add_len )
 {
+    int ret;
     unsigned char work_buf[16];
     size_t i;
     const unsigned char *p;
-    size_t use_len;
+    size_t use_len, olen = 0;
 
     memset( ctx->y, 0x00, sizeof(ctx->y) );
     memset( ctx->buf, 0x00, sizeof(ctx->buf) );
@@ -218,7 +239,11 @@
         gcm_mult( ctx, ctx->y, ctx->y );
     }
 
-    aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->y, ctx->base_ectr );
+    if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
+                             &olen ) ) != 0 )
+    {
+        return( ret );
+    }
 
     ctx->add_len = add_len;
     p = add;
@@ -243,11 +268,12 @@
                 const unsigned char *input,
                 unsigned char *output )
 {
+    int ret;
     unsigned char ectr[16];
     size_t i;
     const unsigned char *p;
     unsigned char *out_p = output;
-    size_t use_len;
+    size_t use_len, olen = 0;
 
     if( output > input && (size_t) ( output - input ) < length )
         return( POLARSSL_ERR_GCM_BAD_INPUT );
@@ -263,7 +289,11 @@
             if( ++ctx->y[i - 1] != 0 )
                 break;
 
-        aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->y, ectr );
+        if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
+                                   &olen ) ) != 0 )
+        {
+            return( ret );
+        }
 
         for( i = 0; i < use_len; i++ )
         {
@@ -613,6 +643,7 @@
     unsigned char buf[64];
     unsigned char tag_buf[16];
     int i, j, ret;
+    cipher_id_t cipher = POLARSSL_CIPHER_ID_AES;
 
     for( j = 0; j < 3; j++ )
     {
@@ -623,7 +654,7 @@
             if( verbose != 0 )
                 printf( "  AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
 
-            gcm_init( &ctx, key[key_index[i]], key_len );
+            gcm_init( &ctx, cipher, key[key_index[i]], key_len );
 
             ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
                                      pt_len[i],
@@ -647,7 +678,7 @@
             if( verbose != 0 )
                 printf( "  AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
 
-            gcm_init( &ctx, key[key_index[i]], key_len );
+            gcm_init( &ctx, cipher, key[key_index[i]], key_len );
 
             ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
                                      pt_len[i],
@@ -671,7 +702,7 @@
             if( verbose != 0 )
                 printf( "  AES-GCM-%3d #%d split (%s): ", key_len, i, "enc" );
 
-            gcm_init( &ctx, key[key_index[i]], key_len );
+            gcm_init( &ctx, cipher, key[key_index[i]], key_len );
 
             ret = gcm_starts( &ctx, GCM_ENCRYPT,
                               iv[iv_index[i]], iv_len[i],
@@ -734,7 +765,7 @@
             if( verbose != 0 )
                 printf( "  AES-GCM-%3d #%d split (%s): ", key_len, i, "dec" );
 
-            gcm_init( &ctx, key[key_index[i]], key_len );
+            gcm_init( &ctx, cipher, key[key_index[i]], key_len );
 
             ret = gcm_starts( &ctx, GCM_DECRYPT,
                               iv[iv_index[i]], iv_len[i],
diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data
index fc0beac..23d4c8c 100644
--- a/tests/suites/test_suite_cipher.aes.data
+++ b/tests/suites/test_suite_cipher.aes.data
@@ -792,3 +792,311 @@
 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
+
+AES-128-ECB Encrypt NIST KAT #1
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"00000000000000000000000000000000":"f34481ec3cc627bacd5dc3fb08f273e6":"0336763e966d92595a567cc9ce537f5e":0
+
+AES-128-ECB Encrypt NIST KAT #2
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"00000000000000000000000000000000":"9798c4640bad75c7c3227db910174e72":"a9a1631bf4996954ebc093957b234589":0
+
+AES-128-ECB Encrypt NIST KAT #3
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"00000000000000000000000000000000":"96ab5c2ff612d9dfaae8c31f30c42168":"ff4f8391a6a40ca5b25d23bedd44a597":0
+
+AES-128-ECB Encrypt NIST KAT #4
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"e0000000000000000000000000000000":"00000000000000000000000000000000":"72a1da770f5d7ac4c9ef94d822affd97":0
+
+AES-128-ECB Encrypt NIST KAT #5
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"f0000000000000000000000000000000":"00000000000000000000000000000000":"970014d634e2b7650777e8e84d03ccd8":0
+
+AES-128-ECB Encrypt NIST KAT #6
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"f8000000000000000000000000000000":"00000000000000000000000000000000":"f17e79aed0db7e279e955b5f493875a7":0
+
+AES-128-ECB Encrypt NIST KAT #7
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"fffffffffffff0000000000000000000":"00000000000000000000000000000000":"7b90785125505fad59b13c186dd66ce3":0
+
+AES-128-ECB Encrypt NIST KAT #8
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"fffffffffffff8000000000000000000":"00000000000000000000000000000000":"8b527a6aebdaec9eaef8eda2cb7783e5":0
+
+AES-128-ECB Encrypt NIST KAT #9
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"fffffffffffffc000000000000000000":"00000000000000000000000000000000":"43fdaf53ebbc9880c228617d6a9b548b":0
+
+AES-128-ECB Encrypt NIST KAT #10
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"ffffffffffffffffffffffffffffc000":"00000000000000000000000000000000":"70c46bb30692be657f7eaa93ebad9897":0
+
+AES-128-ECB Encrypt NIST KAT #11
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"ffffffffffffffffffffffffffffe000":"00000000000000000000000000000000":"323994cfb9da285a5d9642e1759b224a":0
+
+AES-128-ECB Encrypt NIST KAT #12
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"fffffffffffffffffffffffffffff000":"00000000000000000000000000000000":"1dbf57877b7b17385c85d0b54851e371":0
+
+AES-128-ECB Encrypt NIST KAT #13
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"00000000000000000000000000000000":"ffffffffffffffc00000000000000000":"3a4d354f02bb5a5e47d39666867f246a":0
+
+AES-128-ECB Encrypt NIST KAT #14
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"00000000000000000000000000000000":"ffffffffffffffe00000000000000000":"d451b8d6e1e1a0ebb155fbbf6e7b7dc3":0
+
+AES-128-ECB Encrypt NIST KAT #15
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"00000000000000000000000000000000":"fffffffffffffff00000000000000000":"6898d4f42fa7ba6a10ac05e87b9f2080":0
+
+AES-128-ECB Encrypt NIST KAT #16
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"00000000000000000000000000000000":"ffffffffffffffffffffffffe0000000":"082eb8be35f442fb52668e16a591d1d6":0
+
+AES-128-ECB Encrypt NIST KAT #17
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"00000000000000000000000000000000":"fffffffffffffffffffffffff0000000":"e656f9ecf5fe27ec3e4a73d00c282fb3":0
+
+AES-128-ECB Encrypt NIST KAT #18
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_ENCRYPT:"00000000000000000000000000000000":"fffffffffffffffffffffffff8000000":"2ca8209d63274cd9a29bb74bcd77683a":0
+
+AES-128-ECB Decrypt NIST KAT #1
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"00000000000000000000000000000000":"db4f1aa530967d6732ce4715eb0ee24b":"ff000000000000000000000000000000":0
+
+AES-128-ECB Decrypt NIST KAT #2
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"00000000000000000000000000000000":"a81738252621dd180a34f3455b4baa2f":"ff800000000000000000000000000000":0
+
+AES-128-ECB Decrypt NIST KAT #3
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"00000000000000000000000000000000":"77e2b508db7fd89234caf7939ee5621a":"ffc00000000000000000000000000000":0
+
+AES-128-ECB Decrypt NIST KAT #4
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"00000000000000000000000000000000":"dc43be40be0e53712f7e2bf5ca707209":"6a118a874519e64e9963798a503f1d35":0
+
+AES-128-ECB Decrypt NIST KAT #5
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"00000000000000000000000000000000":"92beedab1895a94faa69b632e5cc47ce":"cb9fceec81286ca3e989bd979b0cb284":0
+
+AES-128-ECB Decrypt NIST KAT #6
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"00000000000000000000000000000000":"459264f4798f6a78bacb89c15ed3d601":"b26aeb1874e47ca8358ff22378f09144":0
+
+AES-128-ECB Decrypt NIST KAT #7
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"b69418a85332240dc82492353956ae0c":"a303d940ded8f0baff6f75414cac5243":"00000000000000000000000000000000":0
+
+AES-128-ECB Decrypt NIST KAT #8
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"71b5c08a1993e1362e4d0ce9b22b78d5":"c2dabd117f8a3ecabfbb11d12194d9d0":"00000000000000000000000000000000":0
+
+AES-128-ECB Decrypt NIST KAT #9
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"e234cdca2606b81f29408d5f6da21206":"fff60a4740086b3b9c56195b98d91a7b":"00000000000000000000000000000000":0
+
+AES-128-ECB Decrypt NIST KAT #10
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"ffffffffffffffff0000000000000000":"84be19e053635f09f2665e7bae85b42d":"00000000000000000000000000000000":0
+
+AES-128-ECB Decrypt NIST KAT #11
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_128_ECB:POLARSSL_DECRYPT:"ffffffffffffffff8000000000000000":"32cd652842926aea4aa6137bb2be2b5e":"00000000000000000000000000000000":0
+
+AES-192-ECB Encrypt NIST KAT #1
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"000000000000000000000000000000000000000000000000":"fffffffffffffffffffff80000000000":"156f07767a85a4312321f63968338a01":0
+
+AES-192-ECB Encrypt NIST KAT #2
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"000000000000000000000000000000000000000000000000":"fffffffffffffffffffffc0000000000":"15eec9ebf42b9ca76897d2cd6c5a12e2":0
+
+AES-192-ECB Encrypt NIST KAT #3
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"000000000000000000000000000000000000000000000000":"fffffffffffffffffffffe0000000000":"db0d3a6fdcc13f915e2b302ceeb70fd8":0
+
+AES-192-ECB Encrypt NIST KAT #4
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"000000000000000000000000000000000000000000000000":"51719783d3185a535bd75adc65071ce1":"4f354592ff7c8847d2d0870ca9481b7c":0
+
+AES-192-ECB Encrypt NIST KAT #5
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"000000000000000000000000000000000000000000000000":"26aa49dcfe7629a8901a69a9914e6dfd":"d5e08bf9a182e857cf40b3a36ee248cc":0
+
+AES-192-ECB Encrypt NIST KAT #6
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"000000000000000000000000000000000000000000000000":"941a4773058224e1ef66d10e0a6ee782":"067cd9d3749207791841562507fa9626":0
+
+AES-192-ECB Encrypt NIST KAT #7
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"d2926527e0aa9f37b45e2ec2ade5853ef807576104c7ace3":"00000000000000000000000000000000":"dd619e1cf204446112e0af2b9afa8f8c":0
+
+AES-192-ECB Encrypt NIST KAT #8
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"982215f4e173dfa0fcffe5d3da41c4812c7bcc8ed3540f93":"00000000000000000000000000000000":"d4f0aae13c8fe9339fbf9e69ed0ad74d":0
+
+AES-192-ECB Encrypt NIST KAT #9
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"98c6b8e01e379fbd14e61af6af891596583565f2a27d59e9":"00000000000000000000000000000000":"19c80ec4a6deb7e5ed1033dda933498f":0
+
+AES-192-ECB Encrypt NIST KAT #10
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"fffffffffffffffffffffffffff800000000000000000000":"00000000000000000000000000000000":"8dd274bd0f1b58ae345d9e7233f9b8f3":0
+
+AES-192-ECB Encrypt NIST KAT #11
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"fffffffffffffffffffffffffffc00000000000000000000":"00000000000000000000000000000000":"9d6bdc8f4ce5feb0f3bed2e4b9a9bb0b":0
+
+AES-192-ECB Encrypt NIST KAT #12
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_ENCRYPT:"fffffffffffffffffffffffffffe00000000000000000000":"00000000000000000000000000000000":"fd5548bcf3f42565f7efa94562528d46":0
+
+AES-192-ECB Decrypt NIST KAT #1
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"fffffffffffffffffffffffffffffffff000000000000000":"bb2852c891c5947d2ed44032c421b85f":"00000000000000000000000000000000":0
+
+AES-192-ECB Decrypt NIST KAT #2
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"fffffffffffffffffffffffffffffffff800000000000000":"1b9f5fbd5e8a4264c0a85b80409afa5e":"00000000000000000000000000000000":0
+
+AES-192-ECB Decrypt NIST KAT #3
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"fffffffffffffffffffffffffffffffffc00000000000000":"30dab809f85a917fe924733f424ac589":"00000000000000000000000000000000":0
+
+AES-192-ECB Decrypt NIST KAT #4
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"61257134a518a0d57d9d244d45f6498cbc32f2bafc522d79":"cfe4d74002696ccf7d87b14a2f9cafc9":"00000000000000000000000000000000":0
+
+AES-192-ECB Decrypt NIST KAT #5
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"b0ab0a6a818baef2d11fa33eac947284fb7d748cfb75e570":"d2eafd86f63b109b91f5dbb3a3fb7e13":"00000000000000000000000000000000":0
+
+AES-192-ECB Decrypt NIST KAT #6
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"ee053aa011c8b428cdcc3636313c54d6a03cac01c71579d6":"9b9fdd1c5975655f539998b306a324af":"00000000000000000000000000000000":0
+
+AES-192-ECB Decrypt NIST KAT #7
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"000000000000000000000000000000000000000000000000":"275cfc0413d8ccb70513c3859b1d0f72":"1b077a6af4b7f98229de786d7516b639":0
+
+AES-192-ECB Decrypt NIST KAT #8
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"000000000000000000000000000000000000000000000000":"c9b8135ff1b5adc413dfd053b21bd96d":"9c2d8842e5f48f57648205d39a239af1":0
+
+AES-192-ECB Decrypt NIST KAT #9
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"000000000000000000000000000000000000000000000000":"4a3650c3371ce2eb35e389a171427440":"bff52510095f518ecca60af4205444bb":0
+
+AES-192-ECB Decrypt NIST KAT #10
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"000000000000000000000000000000000000000000000000":"b2099795e88cc158fd75ea133d7e7fbe":"ffffffffffffffffffffc00000000000":0
+
+AES-192-ECB Decrypt NIST KAT #11
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"000000000000000000000000000000000000000000000000":"a6cae46fb6fadfe7a2c302a34242817b":"ffffffffffffffffffffe00000000000":0
+
+AES-192-ECB Decrypt NIST KAT #12
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_192_ECB:POLARSSL_DECRYPT:"000000000000000000000000000000000000000000000000":"026a7024d6a902e0b3ffccbaa910cc3f":"fffffffffffffffffffff00000000000":0
+
+AES-256-ECB Encrypt NIST KAT #1
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"c1cc358b449909a19436cfbb3f852ef8bcb5ed12ac7058325f56e6099aab1a1c":"00000000000000000000000000000000":"352065272169abf9856843927d0674fd":0
+
+AES-256-ECB Encrypt NIST KAT #2
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"984ca75f4ee8d706f46c2d98c0bf4a45f5b00d791c2dfeb191b5ed8e420fd627":"00000000000000000000000000000000":"4307456a9e67813b452e15fa8fffe398":0
+
+AES-256-ECB Encrypt NIST KAT #3
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"b43d08a447ac8609baadae4ff12918b9f68fc1653f1269222f123981ded7a92f":"00000000000000000000000000000000":"4663446607354989477a5c6f0f007ef4":0
+
+AES-256-ECB Encrypt NIST KAT #4
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"0b24af36193ce4665f2825d7b4749c98":"a9ff75bd7cf6613d3731c77c3b6d0c04":0
+
+AES-256-ECB Encrypt NIST KAT #5
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"761c1fe41a18acf20d241650611d90f1":"623a52fcea5d443e48d9181ab32c7421":0
+
+AES-256-ECB Encrypt NIST KAT #6
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"8a560769d605868ad80d819bdba03771":"38f2c7ae10612415d27ca190d27da8b4":0
+
+AES-256-ECB Encrypt NIST KAT #7
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"ffffff80000000000000000000000000":"36aff0ef7bf3280772cf4cac80a0d2b2":0
+
+AES-256-ECB Encrypt NIST KAT #8
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"ffffffc0000000000000000000000000":"1f8eedea0f62a1406d58cfc3ecea72cf":0
+
+AES-256-ECB Encrypt NIST KAT #9
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"ffffffe0000000000000000000000000":"abf4154a3375a1d3e6b1d454438f95a6":0
+
+AES-256-ECB Encrypt NIST KAT #10
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"ffffffffffffffffffffffffffffffffffff8000000000000000000000000000":"00000000000000000000000000000000":"45d089c36d5c5a4efc689e3b0de10dd5":0
+
+AES-256-ECB Encrypt NIST KAT #11
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"ffffffffffffffffffffffffffffffffffffc000000000000000000000000000":"00000000000000000000000000000000":"b4da5df4becb5462e03a0ed00d295629":0
+
+AES-256-ECB Encrypt NIST KAT #12
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_ENCRYPT:"ffffffffffffffffffffffffffffffffffffe000000000000000000000000000":"00000000000000000000000000000000":"dcf4e129136c1a4b7a0f38935cc34b2b":0
+
+AES-256-ECB Decrypt NIST KAT #1
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000":"edf61ae362e882ddc0167474a7a77f3a":"00000000000000000000000000000000":0
+
+AES-256-ECB Decrypt NIST KAT #2
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"fffffffffffffffffffffffffffffffffffffffffffffff80000000000000000":"6168b00ba7859e0970ecfd757efecf7c":"00000000000000000000000000000000":0
+
+AES-256-ECB Decrypt NIST KAT #3
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"fffffffffffffffffffffffffffffffffffffffffffffffc0000000000000000":"d1415447866230d28bb1ea18a4cdfd02":"00000000000000000000000000000000":0
+
+AES-256-ECB Decrypt NIST KAT #4
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"f8be9ba615c5a952cabbca24f68f8593039624d524c816acda2c9183bd917cb9":"a3944b95ca0b52043584ef02151926a8":"00000000000000000000000000000000":0
+
+AES-256-ECB Decrypt NIST KAT #5
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"797f8b3d176dac5b7e34a2d539c4ef367a16f8635f6264737591c5c07bf57a3e":"a74289fe73a4c123ca189ea1e1b49ad5":"00000000000000000000000000000000":0
+
+AES-256-ECB Decrypt NIST KAT #6
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"6838d40caf927749c13f0329d331f448e202c73ef52c5f73a37ca635d4c47707":"b91d4ea4488644b56cf0812fa7fcf5fc":"00000000000000000000000000000000":0
+
+AES-256-ECB Decrypt NIST KAT #7
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"623a52fcea5d443e48d9181ab32c7421":"761c1fe41a18acf20d241650611d90f1":0
+
+AES-256-ECB Decrypt NIST KAT #8
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"38f2c7ae10612415d27ca190d27da8b4":"8a560769d605868ad80d819bdba03771":0
+
+AES-256-ECB Decrypt NIST KAT #9
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"1bc704f1bce135ceb810341b216d7abe":"91fbef2d15a97816060bee1feaa49afe":0
+
+AES-256-ECB Decrypt NIST KAT #10
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"ddc6bf790c15760d8d9aeb6f9a75fd4e":"80000000000000000000000000000000":0
+
+AES-256-ECB Decrypt NIST KAT #11
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"0a6bdc6d4c1e6280301fd8e97ddbe601":"c0000000000000000000000000000000":0
+
+AES-256-ECB Decrypt NIST KAT #12
+depends_on:POLARSSL_AES_C
+test_vec_ecb:POLARSSL_CIPHER_AES_256_ECB:POLARSSL_DECRYPT:"0000000000000000000000000000000000000000000000000000000000000000":"9b80eefb7ebe2d2b16247aa0efc72f5d":"e0000000000000000000000000000000":0
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index 3cd1768..898d98d 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -382,6 +382,53 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void test_vec_ecb( int cipher_id, int operation, char *hex_key,
+                   char *hex_input, char *hex_result,
+                   int finish_result )
+{
+    unsigned char key[50];
+    unsigned char input[16];
+    unsigned char result[16];
+    size_t key_len;
+    cipher_context_t ctx;
+    unsigned char output[32];
+    size_t outlen;
+
+    memset( key, 0x00, sizeof( key ) );
+    memset( input, 0x00, sizeof( input ) );
+    memset( result, 0x00, sizeof( result ) );
+    memset( output, 0x00, sizeof( output ) );
+
+    /* Prepare context */
+    TEST_ASSERT( 0 == cipher_init_ctx( &ctx,
+                                       cipher_info_from_type( cipher_id ) ) );
+
+    key_len = unhexify( key, hex_key );
+    TEST_ASSERT( unhexify( input, hex_input ) ==
+                 (int) cipher_get_block_size( &ctx ) );
+    TEST_ASSERT( unhexify( result, hex_result ) ==
+                 (int) cipher_get_block_size( &ctx ) );
+
+    TEST_ASSERT( 0 == cipher_setkey( &ctx, key, 8 * key_len, operation ) );
+
+    TEST_ASSERT( 0 == cipher_update( &ctx, input,
+                                     cipher_get_block_size( &ctx ),
+                                     output, &outlen ) );
+    TEST_ASSERT( outlen == cipher_get_block_size( &ctx ) );
+    TEST_ASSERT( finish_result == cipher_finish( &ctx, output + outlen,
+                                                 &outlen ) );
+    TEST_ASSERT( 0 == outlen );
+
+    /* check plaintext only if everything went fine */
+    if( 0 == finish_result )
+        TEST_ASSERT( 0 == memcmp( output, result,
+                                  cipher_get_block_size( &ctx ) ) );
+
+    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_gcm.function b/tests/suites/test_suite_gcm.function
index 2b870d1..c9cc177 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -39,7 +39,7 @@
     iv_len = unhexify( iv_str, hex_iv_string );
     add_len = unhexify( add_str, hex_add_string );
 
-    TEST_ASSERT( gcm_init( &ctx, key_str, key_len * 8 ) == init_result );
+    TEST_ASSERT( gcm_init( &ctx, POLARSSL_CIPHER_ID_AES, key_str, key_len * 8 ) == init_result );
     if( init_result == 0 )
     {
         TEST_ASSERT( gcm_crypt_and_tag( &ctx, GCM_ENCRYPT, pt_len, iv_str, iv_len, add_str, add_len, src_str, output, tag_len, tag_output ) == 0 );
@@ -84,7 +84,7 @@
     add_len = unhexify( add_str, hex_add_string );
     unhexify( tag_str, hex_tag_string );
 
-    TEST_ASSERT( gcm_init( &ctx, key_str, key_len * 8 ) == init_result );
+    TEST_ASSERT( gcm_init( &ctx, POLARSSL_CIPHER_ID_AES, key_str, key_len * 8 ) == init_result );
     if( init_result == 0 )
     {
         ret = gcm_auth_decrypt( &ctx, pt_len, iv_str, iv_len, add_str, add_len, tag_str, tag_len, src_str, output );