Add ChaCha20 to the Cipher module
diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h
index ab10a96..d23618e 100644
--- a/include/mbedtls/chacha20.h
+++ b/include/mbedtls/chacha20.h
@@ -121,7 +121,7 @@
  *                  output pointers are NULL.
  *                  Otherwise, 0 is returned to indicate success.
  */
-int mbedtls_chacha20_process( mbedtls_chacha20_context *ctx,
+int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
                               size_t size,
                               const unsigned char *input,
                               unsigned char *output );
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 3ee2ab7..c5a50c0 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -86,6 +86,7 @@
     MBEDTLS_CIPHER_ID_CAMELLIA,  /**< The Camellia cipher. */
     MBEDTLS_CIPHER_ID_BLOWFISH,  /**< The Blowfish cipher. */
     MBEDTLS_CIPHER_ID_ARC4,      /**< The RC4 cipher. */
+    MBEDTLS_CIPHER_ID_CHACHA20,  /**< The Chacha20 cipher. */
 } mbedtls_cipher_id_t;
 
 /**
@@ -145,6 +146,7 @@
     MBEDTLS_CIPHER_CAMELLIA_128_CCM,     /**< Camellia cipher with 128-bit CCM mode. */
     MBEDTLS_CIPHER_CAMELLIA_192_CCM,     /**< Camellia cipher with 192-bit CCM mode. */
     MBEDTLS_CIPHER_CAMELLIA_256_CCM,     /**< Camellia cipher with 256-bit CCM mode. */
+    MBEDTLS_CIPHER_CHACHA20,             /**< Chacha20 stream cipher. */
 } mbedtls_cipher_type_t;
 
 /** Supported cipher modes. */
@@ -190,7 +192,7 @@
 /** Maximum length of any IV, in Bytes. */
 #define MBEDTLS_MAX_IV_LENGTH      16
 /** Maximum block size of any cipher, in Bytes. */
-#define MBEDTLS_MAX_BLOCK_LENGTH   16
+#define MBEDTLS_MAX_BLOCK_LENGTH   64
 
 /**
  * Base cipher information (opaque struct).
diff --git a/library/chacha20.c b/library/chacha20.c
index 75fd9e9..8206a3b 100644
--- a/library/chacha20.c
+++ b/library/chacha20.c
@@ -245,7 +245,7 @@
     return( 0 );
 }
 
-int mbedtls_chacha20_process( mbedtls_chacha20_context *ctx,
+int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
                               size_t size,
                               const unsigned char *input,
                               unsigned char *output )
@@ -333,7 +333,7 @@
     if ( result != 0 )
         goto cleanup;
 
-    result = mbedtls_chacha20_process( &ctx, data_len, input, output );
+    result = mbedtls_chacha20_update( &ctx, data_len, input, output );
 
 cleanup:
     mbedtls_chacha20_free( &ctx );
diff --git a/library/cipher.c b/library/cipher.c
index a5cd61c..68d0c10 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -46,6 +46,10 @@
 #include "mbedtls/ccm.h"
 #endif
 
+#if defined(MBEDTLS_CHACHA20_C)
+#include "mbedtls/chacha20.h"
+#endif
+
 #if defined(MBEDTLS_CMAC_C)
 #include "mbedtls/cmac.h"
 #endif
@@ -231,6 +235,18 @@
             return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
     }
 
+#if defined(MBEDTLS_CHACHA20_C)
+    if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
+    {
+        if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
+                                           iv,
+                                           0U ) ) /* Initial counter value */
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+    }
+#endif
+
     memcpy( ctx->iv, iv, actual_iv_size );
     ctx->iv_size = actual_iv_size;
 
@@ -314,6 +330,16 @@
         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
     }
 
+
+#if defined(MBEDTLS_CHACHA20_C)
+    if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
+    {
+        *olen = ilen;
+        return mbedtls_chacha20_update( (mbedtls_chacha20_context*) ctx->cipher_ctx,
+                                         ilen, input, output );
+    }
+#endif
+
 #if defined(MBEDTLS_CIPHER_MODE_CBC)
     if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
     {
@@ -646,6 +672,11 @@
         return( 0 );
     }
 
+    if ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type )
+    {
+        return( 0 );
+    }
+
     if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
     {
         if( ctx->unprocessed_len != 0 )
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index dc76af8..f4e7964 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -53,6 +53,10 @@
 #include "mbedtls/blowfish.h"
 #endif
 
+#if defined(MBEDTLS_CHACHA20_C)
+#include "mbedtls/chacha20.h"
+#endif
+
 #if defined(MBEDTLS_GCM_C)
 #include "mbedtls/gcm.h"
 #endif
@@ -1283,6 +1287,71 @@
 };
 #endif /* MBEDTLS_ARC4_C */
 
+#if defined(MBEDTLS_CHACHA20_C)
+
+static int chacha20_setkey_wrap( void *ctx, const unsigned char *key,
+                                 unsigned int key_bitlen )
+{
+    if( key_bitlen != 256U )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    if ( 0 != mbedtls_chacha20_setkey( (mbedtls_chacha20_context*)ctx, key ) )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    return( 0 );
+}
+
+static void * chacha20_ctx_alloc( void )
+{
+    mbedtls_chacha20_context *ctx;
+    ctx = mbedtls_calloc( 1, sizeof( mbedtls_chacha20_context ) );
+
+    if( ctx == NULL )
+        return( NULL );
+
+    mbedtls_chacha20_init( ctx );
+
+    return( ctx );
+}
+
+static void chacha20_ctx_free( void *ctx )
+{
+    mbedtls_chacha20_free( (mbedtls_chacha20_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t chacha20_base_info = {
+    MBEDTLS_CIPHER_ID_CHACHA20,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    chacha20_setkey_wrap,
+    chacha20_setkey_wrap,
+    chacha20_ctx_alloc,
+    chacha20_ctx_free
+};
+static const mbedtls_cipher_info_t chacha20_info = {
+    MBEDTLS_CIPHER_CHACHA20,
+    MBEDTLS_MODE_NONE,
+    256,
+    "CHACHA20",
+    12,
+    0,
+    64,
+    &chacha20_base_info
+};
+#endif /* MBEDTLS_CHACHA20_C */
+
 #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
 static int null_crypt_stream( void *ctx, size_t length,
                               const unsigned char *input,
@@ -1438,6 +1507,10 @@
 #endif
 #endif /* MBEDTLS_DES_C */
 
+#if defined(MBEDTLS_CHACHA20_C)
+    { MBEDTLS_CIPHER_CHACHA20,             &chacha20_info },
+#endif
+
 #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
     { MBEDTLS_CIPHER_NULL,                 &null_cipher_info },
 #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 1525bc2..3821657 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -60,6 +60,7 @@
 add_test_suite(cipher cipher.blowfish)
 add_test_suite(cipher cipher.camellia)
 add_test_suite(cipher cipher.ccm)
+add_test_suite(cipher cipher.chacha20)
 add_test_suite(cipher cipher.des)
 add_test_suite(cipher cipher.gcm)
 add_test_suite(cipher cipher.null)
diff --git a/tests/Makefile b/tests/Makefile
index 233259b..34a0a89 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -53,6 +53,7 @@
 	test_suite_chacha20$(EXEXT)	test_suite_cmac$(EXEXT)		\
 	test_suite_cipher.aes$(EXEXT)					\
 	test_suite_cipher.arc4$(EXEXT)	test_suite_cipher.ccm$(EXEXT)	\
+	test_suite_cipher.chacha20$(EXEXT)				\
 	test_suite_cipher.gcm$(EXEXT)					\
 	test_suite_cipher.blowfish$(EXEXT)				\
 	test_suite_cipher.camellia$(EXEXT)				\
@@ -125,6 +126,10 @@
 	echo "  Gen   $@"
 	perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.ccm
 
+test_suite_cipher.chacha20.c : suites/test_suite_cipher.function suites/test_suite_cipher.chacha20.data scripts/generate_code.pl suites/helpers.function suites/main_test.function
+	echo "  Gen   $@"
+	perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.chacha20
+
 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 "  Gen   $@"
 	perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.gcm
@@ -257,6 +262,10 @@
 	echo "  CC    $<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
 
+test_suite_cipher.chacha20$(EXEXT): test_suite_cipher.chacha20.c $(DEP)
+	echo "  CC    $<"
+	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
+
 test_suite_cipher.gcm$(EXEXT): test_suite_cipher.gcm.c $(DEP)
 	echo "  CC    $<"
 	$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $<	$(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
diff --git a/tests/suites/test_suite_cipher.chacha20.data b/tests/suites/test_suite_cipher.chacha20.data
new file mode 100644
index 0000000..5f3e07d
--- /dev/null
+++ b/tests/suites/test_suite_cipher.chacha20.data
@@ -0,0 +1,111 @@
+Decrypt empty buffer
+depends_on:MBEDTLS_CHACHA20_C:
+dec_empty_buf:
+
+ChaCha20 Encrypt and decrypt 0 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:0:-1
+
+ChaCha20 Encrypt and decrypt 1 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:1:-1
+
+ChaCha20 Encrypt and decrypt 2 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:2:-1
+
+ChaCha20 Encrypt and decrypt 7 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:7:-1
+
+ChaCha20 Encrypt and decrypt 8 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:8:-1
+
+ChaCha20 Encrypt and decrypt 9 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:9:-1
+
+ChaCha20 Encrypt and decrypt 15 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:15:-1
+
+ChaCha20 Encrypt and decrypt 16 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:16:-1
+
+ChaCha20 Encrypt and decrypt 17 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:17:-1
+
+ChaCha20 Encrypt and decrypt 31 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:31:-1
+
+ChaCha20 Encrypt and decrypt 32 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:32:-1
+
+ChaCha20 Encrypt and decrypt 33 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:33:-1
+
+ChaCha20 Encrypt and decrypt 47 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:47:-1
+
+ChaCha20 Encrypt and decrypt 48 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:48:-1
+
+ChaCha20 Encrypt and decrypt 49 bytes
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:49:-1
+
+ChaCha20 Encrypt and decrypt 0 bytes in multiple parts 1
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:0:0:-1:0:0:0:0
+
+ChaCha20 Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:1:0:-1:1:0:1:0
+
+ChaCha20 Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:0:1:-1:0:1:0:1
+
+ChaCha20 Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:16:0:-1:16:0:16:0
+
+ChaCha20 Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:0:16:-1:0:16:0:16
+
+ChaCha20 Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:1:15:-1:1:15:1:15
+
+ChaCha20 Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:15:1:-1:15:1:15:1
+
+ChaCha20 Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:15:7:-1:15:7:15:7
+
+ChaCha20 Encrypt and decrypt 22 bytes in multiple parts 2
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:7:15:-1:7:15:7:15
+
+ChaCha20 Encrypt and decrypt 22 bytes in multiple parts 3
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:16:6:-1:16:6:16:6
+
+ChaCha20 Encrypt and decrypt 22 bytes in multiple parts 4
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:6:16:-1:6:16:6:16
+
+ChaCha20 Encrypt and decrypt 32 bytes in multiple parts
+depends_on:MBEDTLS_CHACHA20_C
+enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:16:16:-1:16:16:16:16