Merge tests for asn1write, XTEA and Entropy modules
diff --git a/include/polarssl/entropy.h b/include/polarssl/entropy.h
index 55b262f..f5fa928 100644
--- a/include/polarssl/entropy.h
+++ b/include/polarssl/entropy.h
@@ -183,7 +183,7 @@
  *
  * \param data      Entropy context
  * \param output    Buffer to fill
- * \param len       Length of buffer
+ * \param len       Number of bytes desired, must be at most ENTROPY_BLOCK_SIZE
  *
  * \return          0 if successful, or POLARSSL_ERR_ENTROPY_SOURCE_FAILED
  */
@@ -230,6 +230,15 @@
 int entropy_update_seed_file( entropy_context *ctx, const char *path );
 #endif /* POLARSSL_FS_IO */
 
+#if defined(POLARSSL_SELF_TEST)
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if a test failed
+ */
+int entropy_self_test( int verbose );
+#endif /* POLARSSL_SELF_TEST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/library/entropy.c b/library/entropy.c
index b500491..c01acf3 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -372,4 +372,97 @@
 }
 #endif /* POLARSSL_FS_IO */
 
+#if defined(POLARSSL_SELF_TEST)
+
+#if defined(POLARSSL_PLATFORM_C)
+#include "polarssl/platform.h"
+#else
+#define polarssl_printf     printf
+#endif
+
+/*
+ * Dummy source function
+ */
+static int entropy_dummy_source( void *data, unsigned char *output,
+                                 size_t len, size_t *olen )
+{
+    ((void) data);
+
+    memset( output, 0x2a, len );
+    *olen = len;
+
+    return( 0 );
+}
+
+/*
+ * The actual entropy quality is hard to test, but we can at least
+ * test that the functions don't cause errors and write the correct
+ * amount of data to buffers.
+ */
+int entropy_self_test( int verbose )
+{
+    int ret = 0;
+    entropy_context ctx;
+    unsigned char buf[ENTROPY_BLOCK_SIZE] = { 0 };
+    unsigned char acc[ENTROPY_BLOCK_SIZE] = { 0 };
+    size_t i, j;
+
+    if( verbose != 0 )
+        polarssl_printf( "  ENTROPY test: " );
+
+    entropy_init( &ctx );
+
+    ret = entropy_add_source( &ctx, entropy_dummy_source, NULL, 16 );
+    if( ret != 0 )
+        goto cleanup;
+
+    if( ( ret = entropy_gather( &ctx ) ) != 0 )
+        goto cleanup;
+
+    if( ( ret = entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 )
+        goto cleanup;
+
+    /*
+     * To test that entropy_func writes correct number of bytes:
+     * - use the whole buffer and rely on ASan to detect overruns
+     * - collect entropy 8 times and OR the result in an accumulator:
+     *   any byte should then be 0 with probably 2^(-64), so requiring
+     *   each of the 32 or 64 bytes to be non-zero has a false failure rate
+     *   of at most 2^(-58) which is acceptable.
+     */
+    for( i = 0; i < 8; i++ )
+    {
+        if( ( ret = entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 )
+            goto cleanup;
+
+        for( j = 0; j < sizeof( buf ); j++ )
+            acc[j] |= buf[j];
+    }
+
+    for( j = 0; j < sizeof( buf ); j++ )
+    {
+        if( acc[j] == 0 )
+        {
+            ret = 1;
+            goto cleanup;
+        }
+    }
+
+cleanup:
+    entropy_free( &ctx );
+
+    if( verbose != 0 )
+    {
+        if( ret != 0 )
+            polarssl_printf( "failed\n" );
+        else
+            polarssl_printf( "passed\n" );
+
+        polarssl_printf( "\n" );
+    }
+
+    return( ret != 0 );
+}
+#endif /* POLARSSL_SELF_TEST */
+
 #endif /* POLARSSL_ENTROPY_C */
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 63e4463..0210a19 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -32,6 +32,7 @@
 #include <string.h>
 #include <stdio.h>
 
+#include "polarssl/entropy.h"
 #include "polarssl/hmac_drbg.h"
 #include "polarssl/ctr_drbg.h"
 #include "polarssl/dhm.h"
@@ -193,6 +194,11 @@
         return( ret );
 #endif
 
+#if defined(POLARSSL_ENTROPY_C)
+    if( ( ret = entropy_self_test( v ) ) != 0 )
+        return( ret );
+#endif
+
 /* Slow tests last */
 
 #if defined(POLARSSL_PBKDF2_C)
diff --git a/tests/.gitignore b/tests/.gitignore
index a83ad32..6590f0f 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -3,3 +3,4 @@
 data_files/mpi_write
 data_files/hmac_drbg_seed
 data_files/ctr_drbg_seed
+data_files/entropy_seed
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index cbccebd..b8a125c 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -40,6 +40,7 @@
 add_test_suite(aes aes.cfb)
 add_test_suite(aes aes.rest)
 add_test_suite(arc4)
+add_test_suite(asn1write)
 add_test_suite(base64)
 add_test_suite(blowfish)
 add_test_suite(camellia)
@@ -60,6 +61,7 @@
 add_test_suite(ecp)
 add_test_suite(ecdh)
 add_test_suite(ecdsa)
+add_test_suite(entropy)
 add_test_suite(error)
 add_test_suite(gcm gcm.aes128_en)
 add_test_suite(gcm gcm.aes192_en)
diff --git a/tests/Makefile b/tests/Makefile
index 61e38c4..c37b790 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -32,7 +32,7 @@
 
 APPS =	test_suite_aes.ecb		test_suite_aes.cbc		\
 		test_suite_aes.cfb		test_suite_aes.rest		\
-		test_suite_arc4									\
+		test_suite_arc4			test_suite_asn1write	\
 		test_suite_base64		test_suite_blowfish		\
 		test_suite_camellia		test_suite_ccm			\
 		test_suite_cipher.aes							\
@@ -46,7 +46,7 @@
 		test_suite_des			test_suite_dhm			\
 		test_suite_ecdh			test_suite_ecdsa		\
 		test_suite_ecp									\
-		test_suite_error								\
+		test_suite_error		test_suite_entropy		\
 		test_suite_gcm.aes128_de						\
 		test_suite_gcm.aes192_de						\
 		test_suite_gcm.aes256_de						\
@@ -192,6 +192,10 @@
 	echo   "  CC    	$@.c"
 	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
 
+test_suite_asn1write: test_suite_asn1write.c $(DEP)
+	echo   "  CC    	$@.c"
+	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
+
 test_suite_base64: test_suite_base64.c $(DEP)
 	echo   "  CC    	$@.c"
 	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
@@ -268,6 +272,10 @@
 	echo   "  CC    	$@.c"
 	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
 
+test_suite_entropy: test_suite_entropy.c $(DEP)
+	echo   "  CC    	$@.c"
+	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
+
 test_suite_error: test_suite_error.c $(DEP)
 	echo   "  CC    	$@.c"
 	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
diff --git a/tests/suites/test_suite_asn1write.data b/tests/suites/test_suite_asn1write.data
new file mode 100644
index 0000000..17f2067
--- /dev/null
+++ b/tests/suites/test_suite_asn1write.data
@@ -0,0 +1,50 @@
+ASN.1 Write Octet String #0 (Empty string)
+asn1_write_octet_string:"":"0400":2:2
+
+ASN.1 Write Octet String #1 (Large buffer)
+asn1_write_octet_string:"AABBCC":"0403AABBCC":10:5
+
+ASN.1 Write Octet String #2 (Buffer just fits)
+asn1_write_octet_string:"AABBCC":"0403AABBCC":5:5
+
+ASN.1 Write Octet String #3 (Buffer too small for tag)
+asn1_write_octet_string:"AABBCC":"0403AABBCC":4:POLARSSL_ERR_ASN1_BUF_TOO_SMALL
+
+ASN.1 Write Octet String #4 (Buffer too small for len)
+asn1_write_octet_string:"AABBCC":"0403AABBCC":3:POLARSSL_ERR_ASN1_BUF_TOO_SMALL
+
+ASN.1 Write Octet String #5 (Buffer too small for string)
+asn1_write_octet_string:"AABBCC":"0403AABBCC":2:POLARSSL_ERR_ASN1_BUF_TOO_SMALL
+
+ASN.1 Write Octet String #6 (l = 128, large buffer)
+asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"048180000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":140:131
+
+ASN.1 Write Octet String #7 (l = 128, buffer just fits)
+asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"048180000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":131:131
+
+ASN.1 Write Octet String #8 (l = 128, buffer too small for tag)
+asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"":130:POLARSSL_ERR_ASN1_BUF_TOO_SMALL
+
+ASN.1 Write Octet String #9 (l = 128, buffer too small for len)
+asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"":129:POLARSSL_ERR_ASN1_BUF_TOO_SMALL
+
+ASN.1 Write Octet String #9 (l = 128, buffer too small for string)
+asn1_write_octet_string:"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"":127:POLARSSL_ERR_ASN1_BUF_TOO_SMALL
+
+ASN.1 Write IA5 String #0 (Empty string)
+asn1_write_ia5_string:"":"1600":2:2
+
+ASN.1 Write IA5 String #1 (Large buffer)
+asn1_write_ia5_string:"ABC":"1603414243":10:5
+
+ASN.1 Write IA5 String #2 (Buffer just fits)
+asn1_write_ia5_string:"ABC":"1603414243":5:5
+
+ASN.1 Write IA5 String #3 (Buffer too small for tag)
+asn1_write_ia5_string:"ABC":"":4:POLARSSL_ERR_ASN1_BUF_TOO_SMALL
+
+ASN.1 Write IA5 String #4 (Buffer too small for len)
+asn1_write_ia5_string:"ABC":"":3:POLARSSL_ERR_ASN1_BUF_TOO_SMALL
+
+ASN.1 Write IA5 String #5 (Buffer too small for string)
+asn1_write_ia5_string:"ABC":"":2:POLARSSL_ERR_ASN1_BUF_TOO_SMALL
diff --git a/tests/suites/test_suite_asn1write.function b/tests/suites/test_suite_asn1write.function
new file mode 100644
index 0000000..72e9b4b
--- /dev/null
+++ b/tests/suites/test_suite_asn1write.function
@@ -0,0 +1,84 @@
+/* BEGIN_HEADER */
+#include <polarssl/asn1write.h>
+
+#define GUARD_LEN 4
+#define GUARD_VAL 0x2a
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:POLARSSL_ASN1_WRITE_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE */
+void asn1_write_octet_string( char *hex_str, char *hex_asn1,
+                              int buf_len, int result )
+{
+    int ret;
+    unsigned char buf[150];
+    unsigned char str[150] = { 0 };
+    unsigned char asn1[150] = { 0 };
+    size_t str_len, asn1_len, i;
+    unsigned char *p;
+
+    memset( buf, GUARD_VAL, sizeof( buf ) );
+
+    str_len = unhexify( str, hex_str );
+    asn1_len = unhexify( asn1, hex_asn1 );
+
+    p = buf + GUARD_LEN + buf_len;
+
+    ret = asn1_write_octet_string( &p, buf + GUARD_LEN, str, str_len );
+
+    /* Check for buffer overwrite on both sides */
+    for( i = 0; i < GUARD_LEN; i++ )
+    {
+        TEST_ASSERT( buf[i] == GUARD_VAL );
+        TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
+    }
+
+    if( result >= 0 )
+    {
+        TEST_ASSERT( (size_t) ret == asn1_len );
+        TEST_ASSERT( p + asn1_len == buf + GUARD_LEN + buf_len );
+
+        TEST_ASSERT( memcmp( p, asn1, asn1_len ) == 0 );
+    }
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void asn1_write_ia5_string( char *str, char *hex_asn1,
+                            int buf_len, int result )
+{
+    int ret;
+    unsigned char buf[150];
+    unsigned char asn1[150] = { 0 };
+    size_t str_len, asn1_len, i;
+    unsigned char *p;
+
+    memset( buf, GUARD_VAL, sizeof( buf ) );
+
+    str_len = strlen( str );
+    asn1_len = unhexify( asn1, hex_asn1 );
+
+    p = buf + GUARD_LEN + buf_len;
+
+    ret = asn1_write_ia5_string( &p, buf + GUARD_LEN, str, str_len );
+
+    /* Check for buffer overwrite on both sides */
+    for( i = 0; i < GUARD_LEN; i++ )
+    {
+        TEST_ASSERT( buf[i] == GUARD_VAL );
+        TEST_ASSERT( buf[GUARD_LEN + buf_len + i] == GUARD_VAL );
+    }
+
+    if( result >= 0 )
+    {
+        TEST_ASSERT( (size_t) ret == asn1_len );
+        TEST_ASSERT( p + asn1_len == buf + GUARD_LEN + buf_len );
+
+        TEST_ASSERT( memcmp( p, asn1, asn1_len ) == 0 );
+    }
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_entropy.data b/tests/suites/test_suite_entropy.data
new file mode 100644
index 0000000..d81061c
--- /dev/null
+++ b/tests/suites/test_suite_entropy.data
@@ -0,0 +1,41 @@
+Entropy write/update seed file
+entropy_seed_file:"data_files/entropy_seed":0
+
+Entropy write/update seed file
+entropy_seed_file:"no_such_dir/file":POLARSSL_ERR_ENTROPY_FILE_IO_ERROR
+
+Entropy too many sources
+entropy_too_many_sources:
+
+Entropy output length #1
+entropy_func_len:0:0
+
+Entropy output length #2
+entropy_func_len:1:0
+
+Entropy output length #3
+entropy_func_len:2:0
+
+Entropy output length #4
+entropy_func_len:31:0
+
+Entropy output length #5
+entropy_func_len:65:POLARSSL_ERR_ENTROPY_SOURCE_FAILED
+
+Entropy failing source
+entropy_source_fail:"data_files/entropy_seed"
+
+Entropy threshold #1
+entropy_threshold:16:2:8
+
+Entropy threshold #2
+entropy_threshold:32:1:32
+
+Entropy thershold #3
+entropy_threshold:16:0:POLARSSL_ERR_ENTROPY_SOURCE_FAILED
+
+Entropy thershold #4
+entropy_threshold:1024:1:POLARSSL_ERR_ENTROPY_SOURCE_FAILED
+
+Entropy self test
+entropy_selftest:
diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function
new file mode 100644
index 0000000..844eb96
--- /dev/null
+++ b/tests/suites/test_suite_entropy.function
@@ -0,0 +1,171 @@
+/* BEGIN_HEADER */
+#include <polarssl/entropy.h>
+
+/*
+ * Number of calls made to entropy_dummy_source()
+ */
+static size_t entropy_dummy_calls;
+
+/*
+ * Dummy entropy source
+ *
+ * If data is NULL, write exactly the requested length.
+ * Otherwise, write the length indicated by data or error if negative
+ */
+static int entropy_dummy_source( void *data, unsigned char *output,
+                                 size_t len, size_t *olen )
+{
+    entropy_dummy_calls++;
+
+    if( data == NULL )
+        *olen = len;
+    else
+    {
+        int *d = (int *) data;
+
+        if( *d < 0 )
+            return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
+        else
+            *olen = *d;
+    }
+
+    memset( output, 0x2a, *olen );
+
+    return( 0 );
+}
+/* END_HEADER */
+
+/* BEGIN_DEPENDENCIES
+ * depends_on:POLARSSL_ENTROPY_C
+ * END_DEPENDENCIES
+ */
+
+/* BEGIN_CASE depends_on:POLARSSL_FS_IO */
+void entropy_seed_file( char *path, int ret )
+{
+    entropy_context ctx;
+
+    entropy_init( &ctx );
+
+    TEST_ASSERT( entropy_write_seed_file( &ctx, path ) == ret );
+    TEST_ASSERT( entropy_update_seed_file( &ctx, path ) == ret );
+
+    entropy_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void entropy_too_many_sources( )
+{
+    entropy_context ctx;
+    size_t i;
+
+    entropy_init( &ctx );
+
+    /*
+     * It's hard to tell precisely when the error will occur,
+     * since we don't know how many sources were automatically added.
+     */
+    for( i = 0; i < ENTROPY_MAX_SOURCES; i++ )
+        (void) entropy_add_source( &ctx, entropy_dummy_source, NULL, 16 );
+
+    TEST_ASSERT( entropy_add_source( &ctx, entropy_dummy_source, NULL, 16 )
+                 == POLARSSL_ERR_ENTROPY_MAX_SOURCES );
+
+    entropy_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void entropy_func_len( int len, int ret )
+{
+    entropy_context ctx;
+    unsigned char buf[ENTROPY_BLOCK_SIZE + 10] = { 0 };
+    unsigned char acc[ENTROPY_BLOCK_SIZE + 10] = { 0 };
+    size_t i, j;
+
+    entropy_init( &ctx );
+
+    /*
+     * See comments in entropy_self_test()
+     */
+    for( i = 0; i < 8; i++ )
+    {
+        TEST_ASSERT( entropy_func( &ctx, buf, len ) == ret );
+        for( j = 0; j < sizeof( buf ); j++ )
+            acc[j] |= buf[j];
+    }
+
+    if( ret == 0 )
+        for( j = 0; j < (size_t) len; j++ )
+            TEST_ASSERT( acc[j] != 0 );
+
+    for( j = len; j < sizeof( buf ); j++ )
+        TEST_ASSERT( acc[j] == 0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void entropy_source_fail( char *path )
+{
+    entropy_context ctx;
+    int fail = -1;
+    unsigned char buf[16];
+
+    entropy_init( &ctx );
+
+    TEST_ASSERT( entropy_add_source( &ctx, entropy_dummy_source, &fail, 16 )
+                 == 0 );
+
+    TEST_ASSERT( entropy_func( &ctx, buf, sizeof( buf ) )
+                 == POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
+    TEST_ASSERT( entropy_gather( &ctx )
+                 == POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
+#if defined(POLARSSL_FS_IO)
+    TEST_ASSERT( entropy_write_seed_file( &ctx, path )
+                 == POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
+    TEST_ASSERT( entropy_update_seed_file( &ctx, path )
+                 == POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
+#else
+    ((void) path);
+#endif
+
+    entropy_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void entropy_threshold( int threshold, int chunk_size, int result )
+{
+    entropy_context ctx;
+    unsigned char buf[ENTROPY_BLOCK_SIZE] = { 0 };
+    int ret;
+
+    entropy_init( &ctx );
+
+    TEST_ASSERT( entropy_add_source( &ctx, entropy_dummy_source,
+                                     &chunk_size, threshold ) == 0 );
+
+    entropy_dummy_calls = 0;
+    ret = entropy_func( &ctx, buf, sizeof( buf ) );
+
+    if( result >= 0 )
+    {
+        TEST_ASSERT( ret == 0 );
+        TEST_ASSERT( entropy_dummy_calls == (size_t) result );
+    }
+    else
+    {
+        TEST_ASSERT( ret == result );
+    }
+
+    entropy_free( &ctx );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:POLARSSL_SELF_TEST */
+void entropy_selftest( )
+{
+    TEST_ASSERT( entropy_self_test( 0 ) == 0 );
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_xtea.data b/tests/suites/test_suite_xtea.data
index 37d065c..109e6b6 100644
--- a/tests/suites/test_suite_xtea.data
+++ b/tests/suites/test_suite_xtea.data
@@ -34,6 +34,43 @@
 XTEA Decrypt_ecb #6
 xtea_decrypt_ecb:"00000000000000000000000000000000":"4141414141414141":"70e1225d6e4e7655"
 
+XTEA Encrypt CBC #1
+xtea_encrypt_cbc:"000102030405060708090a0b0c0d0e0f":"6162636465666768":"4142434445464748":"6b982bec15a7b558"
+
+XTEA Encrypt CBC #2
+xtea_encrypt_cbc:"000102030405060708090a0b0c0d0e0f":"4142434445464748":"41414141414141414141414141414141":"2c6aeb799561c8e973b0927f072e3801"
+
+XTEA Encrypt CBC #3
+xtea_encrypt_cbc:"000102030405060708090a0b0c0d0e0f":"0000000000000000":"5a5b6e278948d77f70e1225d6e4e7655e78f2d13744341d8":"41414141414141415fee100fe2c030025d8a557f2677cb33"
+
+XTEA Encrypt CBC #4
+xtea_encrypt_cbc:"00000000000000000000000000000000":"6162636465666768":"4142434445464748":"5b0c065a3803900d"
+
+XTEA Encrypt CBC #5
+xtea_encrypt_cbc:"00000000000000000000000000000000":"4142434445464748":"41414141414141414141414141414141":"bdae508aa320aa5caa7cd79dbc9c38aa"
+
+XTEA Encrypt CBC #6
+xtea_encrypt_cbc:"00000000000000000000000000000000":"0000000000000000":"5a5b6e278948d77f70e1225d6e4e7655e78f2d13744341d8":"61f5082a2c996f632da3ea16ff8e06558b69f069d8637b31"
+
+XTEA Decrypt CBC #1
+xtea_decrypt_cbc:"000102030405060708090a0b0c0d0e0f":"6162636465666768":"4142434445464748":"359def46515c71b2"
+
+XTEA Decrypt CBC #2
+xtea_decrypt_cbc:"000102030405060708090a0b0c0d0e0f":"4142434445464748":"41414141414141414141414141414141":"1b192d63cc0e90371b1a2f66c809963e"
+
+XTEA Decrypt CBC #3
+xtea_decrypt_cbc:"000102030405060708090a0b0c0d0e0f":"0000000000000000":"5a5b6e278948d77f70e1225d6e4e7655e78f2d13744341d8":"2e76e5cc03543cdc40ca03358a5764c331a0631c2f0f3714"
+
+XTEA Decrypt CBC #4
+xtea_decrypt_cbc:"00000000000000000000000000000000":"6162636465666768":"4142434445464748":"81476a15138174dc"
+
+XTEA Decrypt CBC #5
+xtea_decrypt_cbc:"00000000000000000000000000000000":"4142434445464748":"41414141414141414141414141414141":"31a361192b08311d31a0631c2f0f3714"
+
+XTEA Decrypt CBC #6
+xtea_decrypt_cbc:"00000000000000000000000000000000":"0000000000000000":"5a5b6e278948d77f70e1225d6e4e7655e78f2d13744341d8":"c1e2dbbf67ee786e29e051bea18c6abc66f1de5c2daefc2a"
+
 XTEA Selftest
 depends_on:POLARSSL_SELF_TEST
 xtea_selftest:
+
diff --git a/tests/suites/test_suite_xtea.function b/tests/suites/test_suite_xtea.function
index 091752f..74ca678 100644
--- a/tests/suites/test_suite_xtea.function
+++ b/tests/suites/test_suite_xtea.function
@@ -59,6 +59,68 @@
 }
 /* END_CASE */
 
+/* BEGIN_CASE */
+void xtea_encrypt_cbc( char *hex_key_string, char *hex_iv_string,
+                       char *hex_src_string, char *hex_dst_string )
+{
+    unsigned char key_str[100];
+    unsigned char src_str[100];
+    unsigned char dst_str[100];
+    unsigned char iv_str[100];
+    unsigned char output[100];
+    size_t len;
+    xtea_context ctx;
+
+    memset(key_str, 0x00, 100);
+    memset(src_str, 0x00, 100);
+    memset(dst_str, 0x00, 100);
+    memset(iv_str, 0x00, 100);
+    memset(output, 0x00, 100);
+
+    unhexify( key_str, hex_key_string );
+    unhexify( iv_str, hex_iv_string );
+    len = unhexify( src_str, hex_src_string );
+
+    xtea_setup( &ctx, key_str );
+    TEST_ASSERT( xtea_crypt_cbc( &ctx, XTEA_ENCRYPT, len, iv_str,
+                                 src_str, output ) == 0 );
+    hexify( dst_str, output, len );
+
+    TEST_ASSERT( strcmp( (char *) dst_str, hex_dst_string ) == 0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void xtea_decrypt_cbc( char *hex_key_string, char *hex_iv_string,
+                       char *hex_src_string, char *hex_dst_string )
+{
+    unsigned char key_str[100];
+    unsigned char src_str[100];
+    unsigned char dst_str[100];
+    unsigned char iv_str[100];
+    unsigned char output[100];
+    size_t len;
+    xtea_context ctx;
+
+    memset(key_str, 0x00, 100);
+    memset(src_str, 0x00, 100);
+    memset(dst_str, 0x00, 100);
+    memset(iv_str, 0x00, 100);
+    memset(output, 0x00, 100);
+
+    unhexify( key_str, hex_key_string );
+    unhexify( iv_str, hex_iv_string );
+    len = unhexify( src_str, hex_src_string );
+
+    xtea_setup( &ctx, key_str );
+    TEST_ASSERT( xtea_crypt_cbc( &ctx, XTEA_DECRYPT, len, iv_str,
+                                 src_str, output ) == 0 );
+    hexify( dst_str, output, len );
+
+    TEST_ASSERT( strcmp( (char *) dst_str, hex_dst_string ) == 0 );
+}
+/* END_CASE */
+
 /* BEGIN_CASE depends_on:POLARSSL_SELF_TEST */
 void xtea_selftest()
 {